Perché conversione implicita da Long a RichLong non applicare dove si prevede un supertipo di RichLong?

StackOverflow https://stackoverflow.com/questions/3586044

  •  01-10-2019
  •  | 
  •  

Domanda

Scala 2.8 spec dice nel capitolo 7.3 (l'evidenziazione è mia):

  

parametri ei metodi impliciti possono anche definire conversioni implicite chiamati viste.   Una vista dal tipo S di tipo T è definito da un valore implicito che ha funzione tipo   S => T o (=> S) => T o con un metodo convertito in un valore di quel tipo.   Vista vengono applicate in due situazioni.

     
      
  1. Se un'espressione di posta è di tipo T, e T non è conforme per dell'espressione   Tipo pt previsto. In questo caso un implicito v viene cercato che è applicabile a   E e il cui risultato tipo soddisfa per pt. La ricerca procede come nel caso di   Parametri impliciti, dove l'ambito implicito è quello di T => pt. Se un tale   vista viene trovato, l'espressione e viene convertito in v (e).
  2.   
     

[...]

dato il sopra e i seguenti fatti:

  1. Long non è un sottotipo di java.lang.Comparable[Long], cioè non conforme per digitare T dove T <: java.lang.Comaparable[Long]
  2. Predef contiene implicit def longWrapper (x: Long) : RichLong
  3. RichLong è un sottotipo di java.lang.Comparable[Long], cioè conforme per digitare T dove T <: java.lang.Comaparable[Long]

mi aspetto la conversione implicita da applicare dove si incontra Long e si prevede un sottotipo di java.lang.Comparable[Long]. Tuttavia:

scala> def test[T <: java.lang.Comparable[Long]](c: T) = println(c)
test: [T <: java.lang.Comparable[Long]](c: T)Unit

scala> test(12L)
<console>:7: error: inferred type arguments [Long] do not conform to method test's type parameter bounds [T <: java.lang
.Comparable[Long]]
       test(12L)
       ^

Il risultato è come previsto se il valore viene convertito in modo esplicito:

scala> test(longWrapper(12L))
12

Perché la funzione di conversione non viene applicata in modo implicito?

È stato utile?

Soluzione

È necessario utilizzare una vista-bound (<%) per avere il compilatore cercare e applicare la conversione implicita.

scala> def test[T <% java.lang.Comparable[Long]](c: T) = println(c)
test: [T](c: T)(implicit evidence$1: (T) => java.lang.Comparable[Long])Unit

scala> test(12L)
12

Si può leggere di più su vista-bound su questa pagina (Ctrl + F per "vista legato").

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top