2012-03-07 11 views
6

Aquí hay una simplificación de lo que encontré. Esto compila:Implicits y orden de la declaración

trait A { implicit val x = 1 } 
trait B extends A { val y = implicitly[Int] } 

Si bien esto no lo hacen (no podía encontrar el valor implícito):

trait B extends A { val y = implicitly[Int] } 
trait A { implicit val x = 1 } 

Traté de hacer mis intenciones claras mediante la especificación de un auto-tipo: trait A { this: B => ... }, pero fue en vano .

¿Cómo me ocupo de este tipo de dependencias sin preocuparme por cómo se presenta mi código?

Respuesta

11

tiene que declarar el tipo de forma explícita, al menos por esta última

trait B extends A { val y = implicitly[Int] } 
trait A { implicit val x : Int = 1 } 

Las reglas para la visibilidad implícita es diferente si su tipo se declara explícitamente o no. Si no lo es, lo implícito está disponible (como implícito) solo después del punto de declaración.

La razón es que la inferencia de tipo puede volverse demasiado difícil si el tipo no se declaró (como en la rutina recursiva). En muchos casos, la inferencia sería fácil (como en su código) pero la especificación debe ser clara.

+0

¿Qué pasa con los objetos implícitos? ¿Podrías indicarme las partes de las especificaciones con respecto a la resolución de implicidades? 'rasgo X; el rasgo B extiende A {val y = implícitamente [X]}; rasgo A {objeto implícito x extiende X} ' – elbowich

+1

Perdón por respuesta tardía. Después de una mirada más que superficial en la especificación, no pude encontrar la regla. Sin embargo, se menciona en [este informe de error] (https://issues.scala-lang.org/browse/SI-801), parece que es lo que hace la implementación, pero aún no ha llegado a la especificación. No entiendo por qué no debería funcionar con un objeto implícito. –

Cuestiones relacionadas