2017-04-06 48 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'這一行的末尾並在之前打印一些內容。我不想重寫這個論點。 –

相關問題