2012-03-07 22 views
6

ho avuto uno strano bug ieri che alla fine ho ridotto al seguente codice:comportamento imprevisto con impliciti

Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_29). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> class X extends Function[String, Int] { def apply(x: String) = Integer.parseInt(x) } 
defined class X 

scala> implicit val x = new X 
x: X = <function1> 

scala> "56"/2 
res2: Int = 28 

Mi aspetto che questo un'eccezione, dal momento che String non ha un metodo /. Invece, Scala ha trattato la variabile implicita come un metodo implicito (perché implementa Function[String,Int]) e ha convertito la stringa "56" nel numero intero 56.

Come funziona? Basandomi sulle regole della ricerca implicita, non pensavo che le variabili implicite che fungono da funzioni verrebbero prese in considerazione.

+1

Bel preavviso, grazie. – Odomontois

+0

In realtà, una conversione 'implicit def' funziona perché viene automaticamente trasformata in un valore di funzione (ovvero _eta expansion_). –

risposta

7

La semantica delle conversioni implicite è esattamente ciò che hai osservato. Se si definisce una conversione implicita attraverso un metodo implicito,

trait A 
trait B 

implicit def aToB(a : A) : B = new B {} 

vedrai che ora avete un valore di funzione implicita A => B,

scala> implicitly[A => B] 
res1: A => B = <function1> 

E dove si dispone di un metodo con una vista rilegato,

def foo[T <% B](t : T) : B = t 

questo è equivalente a,

def foo[T](t : T)(implicit conv : T => B) : B = conv(t) 

ie. l'argomento implicito corrispondente a una vista vincolata ha esattamente la stessa forma del valore della funzione implicita prodotto da una definizione di metodo implicita.

+0

Quindi i metodi impliciti sono ridotti a variabili implicite di Tipo funzione? O Scala gestisce solo entrambi i casi? – Bill

+1

In qualsiasi contesto in cui il metodo deve essere reificato come valore di funzione (che include le applicazioni che coinvolgono i limiti di vista), sì. Nel mio esempio, se lo hai appena fatto (nuovo A {}: B) il metodo verrebbe applicato senza effettivamente creare prima un oggetto funzione, ma il meccanismo è identico, quindi il comportamento che hai osservato. –

Problemi correlati