Domanda

Non è niente un sottotipo di tutti i tipi?

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)
             ^

È strano che questo non funzioni.

Questo è specificato, una funzione o un bug?

È stato utile?

Soluzione

Quando vedi un comportamento strano che non coinvolge nulla, è perché l'algoritmo di inferenza di tipo pensa di non aver inserito nulla da solo, poiché viene introdotto durante l'inferenza del tipo: se non si sa che nulla di una variabile di tipo, allora è delimitato da qualsiasi e nulla. È stato a lungo nel mio elenco di cose da fare per vedere se posso introdurre un nuovo tipo di fondo solo interno a tale scopo, quindi nulla a livello di utente e nulla a livello di inferenza non è mescolato, ma è un compito piuttosto ambizioso. Tuttavia, ora potrei essere abbastanza hardcore per provarlo.

Altri suggerimenti

Sospetto che Scala non dovrebbe lasciarti fare quel tipo Array[Nothing] istanza. Per definizione non ci sono casi di nulla in giro, eppure il tuo array sembra essere pieno di Nothings null, ma null non è un valore valido per Nothing. Questo ad esempio fallisce con l'errore type mismatch; found : Null(null) required: Nothing

val n: Nothing = null

Quindi mi aspetterei di imbatterti nei guai ogni volta che puoi davvero ingannare il sistema per credere che tu stia finalmente ottenendo un molto ricercato ad esempio Nothing

Ecco un altro caso strano. Esegui questo:

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...
  }

}

Si noti che il tipo di array Scala è invariante. Così Nothing Essere un sottotipo di tutto potrebbe non essere rilevante.

Anche map e filter non sono definiti Array. Conversioni implicite in Predef vengono utilizzati per fornire tali metodi per gli array.

Quindi il compilatore non è in grado di trovare una conversione implicita Array[Nothing] a qualcosa che ha il map o filter definito. Usando la repl, posso effettivamente vedere che dovrebbe essere disponibile una tale conversione implicita:

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)

Quindi la domanda diventa perché il compilatore non considera il genericArrayOps conversione.

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