结合名称冒号操作符和空间不连贯性

时间:2017-04-06 12:52:55

标签: scala

以下是以下问题。当我运行以下内容时:

object  Test {
  def /:(s: => Unit) = {
    println("/:")
    s
  }
}

println("A") /: Test

打印:

A
/:

然而,我期待它打印出来:

/:
A

因为最后一个表达式被认为是重写Test./:(println("A")) - 顺便提一下,它给出了第二个值。

是否有人知道使第一种语法有效的方法,例如println("A") /: Test但是有了名字?

修改

使用desugar方法,我发现调用的方式不同。

> desugar { println("A") /: Test}
 val x$1: Unit = println("A");
 Test./:(x$1)

因此我仍然想知道为什么选择这个。

2 个答案:

答案 0 :(得分:10)

这是known issue。 如果使用-Xlint选项进行编译,则应看到warning

$ scalac -Xlint temp.scala
temp.scala:2: warning: by-name parameters will be evaluated eagerly when called 
              as a right-associative infix operator. For more details, see SI-1980.
    def /:(s: => Unit) = {
        ^
one warning found

答案 1 :(得分:0)

问题是,我认为您期望类型Unit的名称参数 - 只有一个单位,因此名称为:()

我找到了以下作品:

scala> :paste
// Entering paste mode (ctrl-D to finish)

object  Test {
  def /:(s: () => Unit) = {
    println("/:")
    s()
  }
}

val p = () => println("A")
p /: Test

// Exiting paste mode, now interpreting.

/:
A
defined object Test
p: () => Unit = <function0>
res5: Any = ()