首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对象方法不带括号的调用

对象方法不带括号的调用
EN

Stack Overflow用户
提问于 2014-03-20 18:35:55
回答 2查看 800关注 0票数 4

在导入对象方法之后,可以不带括号地调用它吗?

下面是我的测试代码,基于Martin的这篇文章

代码语言:javascript
复制
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中使用这样的方法,使用括号有点烦人。欢迎您的所有建议。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-20 23:09:04

好吧,Scala中的几乎任何东西都是可行的:

代码语言:javascript
复制
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方法。这个对象恰好是动态,所以:

代码语言:javascript
复制
showFruit apple ~~> showFruit.applyDynamic("apple")([Some param, see below])

这意味着我们没有接收到apple对象,而是处理一个"apple" (String)。

因此,我们需要根据它们的字符串名称来查找它们。我正在使用一个映射和一些讨厌的Java反射来实现:)。apple对象实际上是gardening.fruits.apple$,因此我们的f.getClass.getSimpleName方法可以工作。

好吧,既然你知道如何做你想做的事了,请不要这样做。这实际上是一个非常糟糕的方法,模拟post fix操作符语法(也就是说,单凭,不可取)。

这会给你带来各种各样的麻烦。假设您想像这样使用您的方法:

代码语言:javascript
复制
def main(args: Array[String]): Unit = {
    import com.sevenrtc.testreflection.fruits._
    showFruit apple // won't compile
}

但这一汇编如下:

代码语言:javascript
复制
def main(args: Array[String]): Unit = {
    import com.sevenrtc.testreflection.fruits._
    showFruit apple 
    println("Will compile!");
}

为什么?出于同样的原因,这将编译:

代码语言:javascript
复制
def main(args: Array[String]): Unit = {
    import com.sevenrtc.testreflection.fruits._
    showFruit apple 
    ()
}

println (即())的结果实际上正在传递给applyDynamic。因此,第一个例子相当于:

代码语言:javascript
复制
showFruit.apple(println("Will Compile!"))
票数 3
EN

Stack Overflow用户

发布于 2014-03-20 20:12:33

不那是不可能的。e1 op e2是一个所谓的infix操作,相当于e1.op(e2).当忽略接收方(e1)时,这是不起作用的。出于同样的原因,您也不能编写像println "hello"这样的东西。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22542159

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档