2012-03-07 18 views
6

que tenía un extraño insecto ayer que finalmente reduje al siguiente código:comportamiento inesperado con implícitos

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 

espero que esto producirá una excepción, ya cadena no tiene un método /. En cambio, Scala trató la variable implícita como un método implícito (porque implementa Function[String,Int]) y convirtió la cadena "56" al entero 56.

¿Cómo funciona esto? Con base en las reglas de la búsqueda implícita, no pensé que se considerarían las variables implícitas que actúan como funciones.

+1

Aviso agradable, gracias. – Odomontois

+0

En realidad, una conversión 'implicit def' funciona porque se transforma automáticamente en un valor de función (que es _eta expansion_). –

Respuesta

7

La semántica de las conversiones implícitas es exactamente lo que ha observado. Si define una conversión implícita a través de un método implícito,

trait A 
trait B 

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

verá que ahora tiene un valor de la función implícita A => B,

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

Y donde hay un método con el fin de atado,

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

esto es equivalente a,

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

es decir. el argumento implícito correspondiente a una vista vinculada es exactamente de la misma forma que el valor de la función implícita producida por una definición de método implícito.

+0

¿Están los métodos implícitos reducidos a las variables implícitas del tipo de Función? ¿O Scala solo maneja ambos casos? – Bill

+1

En cualquier contexto en el que el método se deba reificar como un valor de función (que incluye aplicaciones que implican límites de vista), sí. En mi ejemplo, si acaba de hacerlo (nuevo A {}: B) el método se aplicaría sin crear realmente un objeto de función primero, pero el mecanismo es idéntico, de ahí el comportamiento que observó. –

Cuestiones relacionadas