在导入对象方法之后,可以不带括号地调用它吗?
下面是我的测试代码,基于Martin的这篇文章:
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中使用这样的方法,使用括号有点烦人。欢迎您的所有建议。
发布于 2014-03-20 23:09:04
好吧,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方法。这个对象恰好是动态,所以:
showFruit apple ~~> showFruit.applyDynamic("apple")([Some param, see below])这意味着我们没有接收到apple对象,而是处理一个"apple" (String)。
因此,我们需要根据它们的字符串名称来查找它们。我正在使用一个映射和一些讨厌的Java反射来实现:)。apple对象实际上是gardening.fruits.apple$,因此我们的f.getClass.getSimpleName方法可以工作。
好吧,既然你知道如何做你想做的事了,请不要这样做。这实际上是一个非常糟糕的方法,模拟post fix操作符语法(也就是说,单凭,不可取)。
这会给你带来各种各样的麻烦。假设您想像这样使用您的方法:
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!"))发布于 2014-03-20 20:12:33
不那是不可能的。e1 op e2是一个所谓的infix操作,相当于e1.op(e2).当忽略接收方(e1)时,这是不起作用的。出于同样的原因,您也不能编写像println "hello"这样的东西。
https://stackoverflow.com/questions/22542159
复制相似问题