¿Por qué es la conversión implícita de largo a RichLong no aplicarse cuando se espera un supertipo de RichLong?
-
01-10-2019 - |
Pregunta
Scala spec 2,8 dice en la sección 7.3 (el resaltado es mío):
parámetros y métodos implícitos también pueden definir conversiones implícitas llamados puntos de vista. Una vista desde Tipo S para escribir T se define por un valor implícito que tiene el tipo de función S => T o (=> S) => T o por un método convertible a un valor de ese tipo. Las vistas se aplica en dos situaciones.
- Si una expresión e es de tipo T y T no se ajusta ??strong> a las de expresión pt tipo esperado. En este caso, una v implícita se busca que es aplicable a e y cuyo resultado tipo cumpla a pt. La búsqueda procede como en el caso de parámetros implícitos, donde el alcance implícito es la de T => pt. Si por ejemplo una visión se encuentra, la expresión e se convierte en v (e).
[...]
Dado lo anterior y en los siguientes hechos:
-
Long
no es un subtipo dejava.lang.Comparable[Long]
, es decir, no se ajusta ??strong> para escribirT
dondeT <: java.lang.Comaparable[Long]
-
Predef
contieneimplicit def longWrapper (x: Long) : RichLong
-
RichLong
es un subtipo dejava.lang.Comparable[Long]
, es decir, ajusta ??strong> para escribirT
dondeT <: java.lang.Comaparable[Long]
Yo esperaría que la conversión implícita a aplicarse cuando se encuentra Long
y se espera un subtipo de java.lang.Comparable[Long]
. Sin embargo:
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)
^
El resultado es el esperado si el valor se convierte de forma explícita:
scala> test(longWrapper(12L))
12
¿Por qué no se aplica la función de conversión implícita?
Solución
Es necesario utilizar una vista determinada (<%
) tener compilador de conseguir y aplicar la conversión implícita.
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
Puede leer más acerca de vista determinada sobre esta página (Ctrl + F para "vista obligado").