对象方法调用不带括号 [英] Object methods call without parentheses

查看:78
本文介绍了对象方法调用不带括号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

导入后是否可以在不带括号的情况下调用对象方法?

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆