2017-04-06 3 views
8

次の問題があります。名前によるコール・コロン演算子とスペース・インコヒーレンシを結合します

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

println("A") /: Test 

それが印刷されます:私は次のように実行すると

A 
/: 

をしかし、私は印刷にそれを期待していた。

/: 
A 

最後の式は、おそらくTest./:(println("A"))を書き直されたため - これにより、方法は、2番目の値を与える。

誰かが最初の構文作業を行う方法を知っていますか? 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の名前のパラメータを期待していると思います。ユニットが1つしかないので、名前は()です。

私は、次の作品を見つけました:

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'行の最後に書いて、何かを前もって印刷したいと思っています。私は議論自体を書き直したくない。 –

関連する問題