Tienes que mirar en la siguiente línea como dos partes separadas, el lado izquierdo de la = y el derecho:
val oB: Option[B] = collectFirstOf(List(new A,new B))
Lo que están esperando aquí es que el tipo de la expresión collectFirstOf (el valor r) debe inferirse del tipo del valor de OB. El compilador no puede hacer esto. Tienes que decir específicamente qué tipo estás esperando. Tome el siguiente ejemplo:
val v: Long = 1 + 4
El tipo de la expresión 1 + 4 es un Int. Este int se convierte en Long. El compilador no puede deducir que desea que el 1 o el 4 sean largos:
Por lo tanto, para solucionar su problema, debe indicar al compilador qué tipo está esperando, de lo contrario, asume java.lang.Object:
val oB = collectFirstOf[B](List(new A,new B))
Así que el manifiesto se asigna correctamente, y todo está bien con el mundo. Entonces, ¿por qué el siguiente incluso compilar:
val oB:Option[B] = collectFirstOfT(List(new A,new B))
oB: Option[B] = Some([email protected])
a primera vista, no parece que esto debería funcionar, pero lo hace. Esto se debe a la collectFirstOfT devuelve realmente una opción [Nada], que se puede convertir de manera segura a una Opción [B]:
scala> val f = collectFirstOfT(List(new A,new B))
f: Option[Nothing] = Some([email protected])
scala> f.asInstanceOf[Option[B]]
res4: Option[B] = Some([email protected])
¡Buena captura! ¿Cómo puedo evitar que la función sea mal utilizada? (Idealmente, no debería compilarse) – jwinandy
Una manera rápida y fácil sería agregar un argumento explícito, la clase: collectFirstOfT [T] (cls: Class [T], la: List [_]), luego llamar como: collectFirstOfT (classOf [B], List (nuevo A, nuevo B)). Esto devolvería una Opción [B] como se esperaba. –