Perché conversione implicita da Long a RichLong non applicare dove si prevede un supertipo di RichLong?
-
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.
- 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).
[...]
dato il sopra e i seguenti fatti:
-
Long
non è un sottotipo dijava.lang.Comparable[Long]
, cioè non conforme per digitareT
doveT <: java.lang.Comaparable[Long]
-
Predef
contieneimplicit def longWrapper (x: Long) : RichLong
-
RichLong
è un sottotipo dijava.lang.Comparable[Long]
, cioè conforme per digitareT
doveT <: 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?
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").