在我的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:Boolean,onDisable:Boolean)(c: 组件)依赖于类Test的组件和方法(c: 组件)组件匹配预期类型?
但如果我将参数括在括号中:
val compB = dependant(Component("parameters"))
错误消失了。显然,编译器在使用无括号的情况下失败了。这是预期还是我做错了什么?如果这是预期的,那么为什么呢?如何回收使用方法dependant
作为前缀的能力,不带括号?
答案 0 :(得分:2)
如果你提供一个对象,写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)))
答案 1 :(得分:2)
在dependant Component("parameters")
中,您尝试使用前缀表示法来调用dependant
。 Scala对前缀表示法的支持是有限的。
请参阅Scala - Prefix Unary Operators。
另一种方法是使用后缀表示法(如Component("parameters") dependant
中所述)。
如果您可以修改Componenet的实现,这只是意味着将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
,则可以使用“pimp my library idiom”。
有关此习语的简短介绍,请参阅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
}