对象方法调用不带括号 [英] Object methods call without parentheses
问题描述
导入后是否可以在不带括号的情况下调用对象方法?
Is it possible to call an object method without parentheses, after import it ?
这是我的测试代码,基于这篇文章作者:马丁·奥德斯基(Martin Odersky):
Here is my test code, based on this article by Martin Odersky:
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
}
}
导入包对象水果
之后,我可以调用方法 showFruit(apple)
,但是有没有办法像上面的代码末尾一样不带括号来调用该方法?
After importing the package object fruits
, I can call the method showFruit(apple)
, but is there any way to call the method without parentheses like the last of the code ?
我使用了此类方法在一点点DSL中,使用括号有点烦人。欢迎您提出所有建议。
I use such of methods in a little DSL and it is a bit annoying to use parentheses. All your suggestions are welcome.
推荐答案
Scala中的几乎所有内容都是可行的:
Well, almost anything in Scala is doable:
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)
}
}
}
将使您的代码正常工作。
Will make your code work.
我们将原来的 showFruit
方法替换为目的。该对象恰巧是动态,因此:
We are replacing the original showFruit
method with an object. This object happens to be Dynamic, so:
showFruit apple ~~> showFruit.applyDynamic("apple")([Some param, see below])
这意味着我们没有收到 apple
对象,我们正在处理 apple
( String
)。
Which means that we are not receiving the apple
object, we are dealing with an "apple"
(String
).
因此,我们需要根据其字符串名称查找水果。我为此使用了地图和一些讨厌的Java反射:)。 apple
对象实际上是 gardening.fruits.apple $
,因此我们的 f.getClass。 getSimpleName
方法有效。
So we need to lookup fruits according to their string names. I'm using a map and some nasty Java Reflection for this :). The apple
object is actually gardening.fruits.apple$
, so our f.getClass.getSimpleName
approach works.
好吧,既然您知道该怎么做,请不要。这实际上是一个模拟后修复运算符语法的非常坏的解决方法(不建议单独使用 )。
Well, now that you know how to do what you want, please don't. This is actually a really broken workaround simulating post fix operator syntax (which is, by itself, not advisable) .
这会给您带来各种麻烦。假设您要使用这样的方法:
This will put you in all sorts of trouble. Say you want to use your method like this:
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!");
}
为什么?出于以下相同的原因进行编译:
Why? For the same reason that this compiles:
def main(args: Array[String]): Unit = {
import com.sevenrtc.testreflection.fruits._
showFruit apple
()
}
println
的结果(即()
)实际上已传递给 applyDynamic
。因此,第一个示例等效于:
The result of println
(which is ()
) is actually being passed to applyDynamic
. So the first example is equivalent to:
showFruit.apple(println("Will Compile!"))
这篇关于对象方法调用不带括号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!