Pregunta

¿No es nada un subtipo de todo tipo?

scala> val array = new Array(5)
array: Array[Nothing] = Array(null, null, null, null, null)

scala> array.map(_ => 42)
<console>:9: error: value map is not a member of Array[Nothing]
       array.map(_ => 42)
             ^

scala> array.filter(_ != 42)
<console>:9: error: value filter is not a member of Array[Nothing]
       array.filter(_ != 42)
             ^

Es extraño que esto no funcione.

¿Se especifica esto, una característica o un error?

¿Fue útil?

Solución

Cuando ves un comportamiento extraño que no implica nada, es porque el algoritmo de inferencia de tipo cree que no insertó nada en sí mismo, ya que se introduce durante la inferencia de tipo: si no se sabe nada sobre una variable de tipo, entonces está limitado por cualquiera y nada. Durante mucho tiempo ha estado en mi lista de cosas para ver si puedo introducir un nuevo tipo inferior interno para ese propósito, por lo que nada a nivel de usuario y nada de inferencia no se entremezclan, pero es una tarea bastante ambiciosa. Aún así, ahora podría ser lo suficientemente duro como para probarlo.

Otros consejos

Sospecho que Scala no debería dejarte hacer ese tipo de Array[Nothing] instanciación. Por definición, no hay casos de nada alrededor, pero su matriz parece estar llena de Nothings que son nulos, pero nulo no es un valor válido para Nothing. Esto, por ejemplo, falla con el error type mismatch; found : Null(null) required: Nothing

val n: Nothing = null

Por lo tanto, esperaría tener problemas cada vez que pueda engañar al sistema para creer que finalmente se está apoderando de un muy solicitado por ejemplo de Nothing

Aquí hay otro caso extraño. Ejecuta esto:

object Main {

  class Parametrized[T] { var value: T = _ }

  def main(args: Array[String]) {
    val p = new Parametrized // typed as Parametrized[Nothing]
    val n = p.value  // n is now actually an instance of Nothing... isn't it?
    println(p.value) // prints null, but null is not an instance of Nothing
    println(n)       // throws NullPointerException...
  }

}

Tenga en cuenta que el tipo de matriz Scala es invariante. Asi que Nothing Ser un subtipo de todo puede no ser relevante.

También map y filter no están definidos en Array. Conversiones implícitas en Predef se utilizan para proporcionar tales métodos para matrices.

Entonces, el compilador no puede encontrar una conversión implícita de Array[Nothing] a algo que tiene el map o filter definido. Usando el Reply, puedo ver que una conversión tan implícita debería estar disponible:

scala> val conv = implicitly[Array[Nothing] <%< collection.mutable.ArrayOps[Nothing]]

conv: <%<[Array[Nothing],scala.collection.mutable.ArrayOps[Nothing]] = <function1>

scala> conv(new Array[Nothing](5)).filter(_ => true)
res8: Array[Nothing] = Array(null, null, null, null, null)

Entonces, la pregunta es por qué el compilador no considera el genericArrayOps conversión.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top