在我的DSL中,我想要这个功能:
class Test {
val compA = dependant(true, true)(Component("parameters"))
//and this shortcut:
val compB = dependant Component("parameters")
}
其中:
def dependant(onEnable: Boolean, onDisable: Boolean)(c: Component): Component = {
//...
}
def dependant(c: Component): Component = dependant(false, true)(c)
一切都很好,但是,我不能使用以下语法:
val compB = dependant Component("parameters")
因为上面写着
对重载定义的引用不明确,两者都依赖于中的方法class类型的测试(onEnable:布尔,onDisable:布尔)(c:组件)依赖于组件和方法的类内测试类型(c:组件)组件是否符合预期类型?
但如果我把参数放在括号里:
val compB = dependant(Component("parameters"))
错误消失了。显然,编译器在取消加括号的情况下失败了。这是意料之中的事,还是我做错了什么?如果这是意料之中的事,那么为什么?如何恢复使用方法dependant
作为前缀而不使用括号的能力?
在dependant Component("parameters")
中,您正试图使用前缀表示法来调用dependant
。Scala对前缀表示法的支持是有限的。
请参阅Scala-前缀一元运算符。
另一种选择是使用后缀表示法(如Component("parameters") dependant
)。如果您可以修改Componentet的实现,这只意味着将dependant
方法添加到Component
:
class Component(name: String) {
def dependant: Component = //...
def dependant(onEnable: Boolean, onDisable: Boolean): Component = {
//...
}
}
class Test {
val compA = Component("parameters") dependant(true, true)
val compB = Component("parameters") dependant
}
如果你不能修改Component
,你可以使用"拉皮条我的图书馆习语"。看见http://www.decodified.com/scala/2010/12/02/the-quickpimp-pattern.html关于这个习惯用法的简短介绍(以及下面关于使用匿名类的警告):
case class Component(name: String)
implicit def toPostifxDependentOps( c: Component ) = new {
def dependant: Component = dependant(false, true)
def dependant(onEnable: Boolean, onDisable: Boolean): Component = {
//...
}
}
class Test {
val compA = Component("parameters") dependant(true, true)
val compB = Component("parameters") dependant
}
如果提供对象,则编写myObject functionName param
而不是myObject.functionName(param)
可以正常工作。如果不这样做,编译器将丢失。例如:
scala> println("Hello")
Hello
scala> println "Hello"
<console>:1: error: ';' expected but string literal found.
println "Hello"
^
一个可能的解决方法:创建一个对象来包装你的方法:
scala> case class Component(name: String, components: Option[Component] = None)
defined class Component
scala> object depends {def on(c: Component) = Component("dependant", Some(c))}
defined module depends
scala> depends on Component("foo")
res3: Component = Component(dependant,Some(Component(foo,None)))