2017-04-06 46 views
8

以下是以下问题。当我运行以下命令:组合名称为冒号的操作符和空间异性

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) 

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

+1

为什么你“假设”表达式等同于'Test ./ :(:(println(“A”))'?该规范说:“左联合二进制操作'e1 op e2'被解释为'e1.op(e2)',如果op是右联合的,则相同的操作被解释为'{val x = e1; e2.op(x)}',其中'x'是一个新名字。“所以,它相当于'{val x = println(“A”); Test./:(x)}'。 –

回答

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 
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 =() 
+0

我敢打赌这项工作,但问题不在于单位。我希望能够写入':/ Test'这一行的末尾并在之前打印一些内容。我不想重写这个论点。 –

相关问题