导入后是否可以调用没有括号的对象方法?
这是我的测试代码,基于Martin Odersky的this article:
package gardening.fruits
object PrintPlanted {
def main(args: Array[String]) {
// Call method on object
import gardening.fruits
fruits showFruit(apple)
fruits showFruit apple
// Import object
import gardening.fruits._
showFruit(apple)
// showFruit apple
// Error: missing arguments for method showFruit in package fruits;
// follow this method with `_' if you want to treat it
// as a partially applied function
}
}
导入包对象fruits
后,我可以调用方法showFruit(apple)
,但有没有办法调用方法而没有括号,如最后一个代码?
我在一个小DSL中使用这样的方法,使用括号有点烦人。欢迎您提出所有建议。
答案 0 :(得分:2)
不,这是不可能的。 e1 op e2
是所谓的中缀操作,相当于e1.op(e2)
。当接收器(e1
)被遗漏时,这不起作用。出于同样的原因,你也不能写println "hello"
之类的东西。
答案 1 :(得分:2)
好吧,Scala中几乎所有东西都可行:
package object fruits {
val planted = List(apple, plum, banana)
import scala.language.dynamics
object showFruit extends Dynamic {
private val lookupFruit = planted
.map(f => (f.getClass.getSimpleName, f)).toMap;
def applyDynamic(name: String)(args: Any*) = {
realShowFruit(lookupFruit(name+"$"));
}
private def realShowFruit(fruit: Fruit) = {
println(fruit.name + "s are " + fruit.color)
}
}
}
将使您的代码有效。
我们正在用对象替换原始的showFruit
方法。这个对象恰好是Dynamic,所以:
showFruit apple ~~> showFruit.applyDynamic("apple")([Some param, see below])
这意味着我们没有收到apple
个对象,我们正在处理"apple"
(String
)。
因此我们需要根据字符串名称查找水果。我正在使用地图和一些讨厌的Java反射:)。 apple
对象实际上是gardening.fruits.apple$
,因此我们的f.getClass.getSimpleName
方法有效。
嗯,既然你知道如何做你想做的事,请不要。这实际上是一个真正破解的解决方法,模拟了post fix operator语法(by itself,不可取)。
这会给你带来各种各样的麻烦。假设你想使用这样的方法:
def main(args: Array[String]): Unit = {
import com.sevenrtc.testreflection.fruits._
showFruit apple // won't compile
}
但这会编译:
def main(args: Array[String]): Unit = {
import com.sevenrtc.testreflection.fruits._
showFruit apple
println("Will compile!");
}
为什么呢?出于同样的原因,这个编译:
def main(args: Array[String]): Unit = {
import com.sevenrtc.testreflection.fruits._
showFruit apple
()
}
println
(()
)的结果实际上传递给applyDynamic
。所以第一个例子相当于:
showFruit.apple(println("Will Compile!"))