なぜマップ/フィルターは、何もない配列で動作しないのですか?
-
27-10-2019 - |
質問
すべてのタイプのサブタイプではありませんか?
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)
^
これがうまくいかないのは奇妙です。
これは指定されていますか、機能、またはバグですか?
解決
何も関与していない奇妙な動作が見えるとき、それはタイプの推論中に導入されるため、タイプの推論アルゴリズムがそれ自体を挿入していると考えているためです。タイプ変数について何も知られていない場合、それは任意のものと何も境界に縛られていません。その目的のために新しい内部のみのボトムタイプを導入できるかどうかを確認するために私のやることのリストに長い間ありましたので、ユーザーレベルは何もなく、推論レベルは混ざり合っていませんが、それはかなり野心的な作業です。それでも、私は今それを試すのに十分な筋金入りかもしれません。
他のヒント
Scalaがあなたにそのようなことをさせてはいけないと思う Array[Nothing]
インスタンス化。定義上、何もないインスタンスはありませんが、あなたの配列はそれがいっぱいになっているように見えます Nothing
nはnullですが、nullは有効な値ではありません Nothing
. 。たとえば、これはエラーでは失敗します type mismatch; found : Null(null) required: Nothing
val n: Nothing = null
ですから、私はあなたが実際にシステムをだますことができるたびに、あなたが最終的に多くの人気のあるものを手に入れていると信じることができると期待しています Nothing
…
これが別の奇妙なケースです。これを実行:
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...
}
}
SCALAアレイタイプは不変であることに注意してください。そう Nothing
すべてのサブタイプであることは関連性がない場合があります。
また map
と filter
で定義されていません Array
. 。暗黙の変換 Predef
アレイにそのような方法を提供するために使用されます。
そのため、コンパイラはからの暗黙の変換を見つけることができません Array[Nothing]
持っている何かに map
また filter
定義されています。 REPLを使用して、私は実際にそのような暗黙の変換が利用可能であるべきであることがわかります:
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)
ですから、質問はコンパイラが考慮しない理由になります genericArrayOps
変換。