2015-07-07 8 views
7

Vediamo il codice qui sotto:Scala conversione implicita sul parametro di chiamata per nome funziona in modo diverso a seconda della funzione è sovraccarico o non

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 
} 

Questo codice non stampa nulla, perché il blocco contiene println("Hello") trattati come => Int ed è convertito in Foo entro il int2Foo. Ma la cosa sorprendente è accaduto se omettiamo la funzione sovraccaricata 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 
} 

Questo stampa Hello perché valuta il blocco, e solo l'ultima istruzione, 64 in questo caso, viene considerato come parametro di chiamata per nome . Non riesco a capire che tipo di logica esista dietro questa differenza.

+1

Problema correlato: https://issues.scala-lang.org/browse/SI-3237 –

+0

Questo comportamento non è previsto, a meno che non manchi qualcosa. Anche se è conforme alle specifiche, è estremamente controintuitivo ed è seriamente soggetto a bug (ad esempio, se qualcuno rimuove un sovraccarico apparentemente usato da nessuna parte, causando in tal modo che il parametro by-name si comporti diversamente). –

+0

Disporre il blocco in '{...}: Int' cambia anche il comportamento. –

risposta

1

Penso che le specifiche di Scala siano ambigue su come le viste implicite dovrebbero essere applicate qui. In altre parole, entrambi i seguenti interpretazioni della dichiarazione sono conformi alle specifiche:

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

Naturalmente, è estremamente controintuitivo per un sovraccarico estraneo a influenzare questo comportamento. Mi sembra che il comportamento, sebbene ambiguo, dovrebbe almeno essere coerente. Questo deve essere un dettaglio di implementazione delle interazioni del compilatore tra la risoluzione del sovraccarico, i parametri del nome e le viste implicite. Ho depositato SI-9386 per risolvere il problema.

+0

Wow, grazie per aver archiviato il problema! – pocorall