2015-07-07 10 views
7

Lassen Sie sich den Code unten:Scala implizite Konvertierung auf Call-by-name-Parameter funktioniert unterschiedlich, je nach Funktion überlastet ist oder nicht

import scala.language.implicitConversions 
class Foo 
implicit def int2Foo(a: => Int): Foo = new Foo 
def bar(foo: Foo) = {} 
def bar(foo: Boolean) = {} 
bar { 
    println("Hello") 
    64 
} 

Dieser Code hat nichts drucken, weil der Block println("Hello") behandelt enthält als => Int und wird durch int2Foo in Foo umgewandelt. Aber die überraschende Sache ist passiert, wenn wir die überladene Funktion bar(foo: Boolean)

import scala.language.implicitConversions 
class Foo 
implicit def int2Foo(a: => Int): Foo = new Foo 
def bar(foo: Foo) = {} 
bar { 
    println("Hello") 
    64 
} 

Dies druckt Hello weglassen, weil sie den Baustein wertet, und nur die letzte Anweisung, 64 in diesem Fall als Call-by-name-Parameter behandelt wird . Ich kann nicht verstehen, welche Art von Begründung hinter diesem Unterschied existiert.

+1

Verwandte Problem: https://issues.scala-lang.org/browse/SI-3237 –

+0

Es gibt keine Möglichkeit, dieses Verhalten beabsichtigt ist, es sei denn, ich vermisse etwas. Selbst wenn es der Spezifikation entspricht, ist es extrem kontraintuitiv und ist ernsthaft fehleranfällig (z. B. was, wenn jemand eine Überladung entfernt, die anscheinend nirgendwo verwendet wird, wodurch bewirkt wird, dass sich der by-name-Parameter anders verhält). –

+0

Das Umbrechen des Blocks in '{...}: Int' ändert auch das Verhalten. –

Antwort

1

Ich denke, die Scala-Spezifikation ist mehrdeutig darüber, wie implizite Ansichten hier angewendet werden sollten. Mit anderen Worten entsprechen die beiden folgenden Interpretationen der Aussage der Spezifikation:

bar { println("Hello"); int2Foo(64) } 
bar { int2Foo({ println("Hello"); 64 }) } 

Natürlich ist es extrem eingängig für ein nicht verwandtes Überlastung dieses Verhalten zu beeinflussen. Es scheint mir, dass das Verhalten, obwohl mehrdeutig, zumindest konsistent sein sollte. Dies muss ein Implementierungsdetail der Compilerinteraktionen zwischen Überladungsauflösung, Parameternamen und impliziten Sichten sein. Ich habe SI-9386 eingereicht, um das Problem zu beheben.

+0

Wow, danke für die Einreichung des Problems! – pocorall