クラスの階層の下部にないタイプがない場合、なぜ考えられる方法を呼び出すことができないのですか?
質問
SCALAタイプ Nothing
私が理解しているように)は、シンボル⊥でも示されるタイプの階層の底を表します。あれは、 Nothing
特定のタイプのサブタイプです。 aの要件 Nothing
タイプはです ジェームズ・アイリーがよく説明しました タイプ理論の理論的背景のない私たちのために!
だから私の質問は、です Nothing
あらゆるタイプのサブタイプです、なぜ私はどんなタイプのメソッドを呼び出せないのですか Nothing
?明らかに、私は何もインスタンス化することはできませんが、なぜ次のコンパイルをしないのですか?
var n: Nothing = _
def main(args: Array[String]) {
println(n.length) //compile error: value length is not a member of Nothing
}
確かに Nothing
のサブタイプです String
これは大丈夫ですか?次のコンパイルは正常にコンパイルされていることに注意してください!
var n: Nothing = _
def foo(s: String) : Int = s.length
def main(args: Array[String]) {
println(foo(n))
}
そうであるように:
def main(args: Array[String]) {
println(n.asInstanceOf[String].length)
}
解決
その間 Nothing
すべてのサブタイプであり、そうではありません 継承 それらを除くすべての方法 Any
. 。それの訳は Nothing
言語の機能的端に向けられています。のようなものが必要です Option
と List
, 、しかし、のみ タイプ, 、クラスとしてではありません。
ここでの区別は、オブジェクト指向の背景から来る人にとっては少し奇妙ですが、実際には、概念としてのサブタイプはOOPとは非常に異なるということです。確かに、オブジェクト指向は実際に何らかの形でサブタイピングを意味しますが、逆は真実ではありません。ベンジャミン・ピアス タイプとプログラミング言語 言語を提示するのは良い仕事をしています f_ (「F Sub」と発音)。これは、サブタイピングを持つ言語の最小限の例として機能します(OOではありません)。
さて、そうは言っても、私はその事実に同意します Nothing
通常の継承ルールからの免疫は、少し矛盾しているように見えます。しかし、理論的な観点からは、それは完全に理にかなっています。
他のヒント
私は考えます Nothing
任意の方法を受け入れ、すべての方法で標準操作を実行できます(例外をスローします)。しかし、それはあまり役に立ちません。
コンパイルエラーを提示することにより、コンパイラはプログラマーに、彼が望んでいない可能性が最も高いタイプであることを警告しています。 Nothing
, 、コードの特定の時点で何らかの形で推測されました。
あなたは電話することができます toString
の上 Nothing
そのための変数は、defintion:
final trait Nothing extends Any
そして、ToStringはメンバーです Any
. 。 Scala Compiler Treatのものだと思います Nothing
タイプの境界のみで、すべてのケースの他の特性のように扱います。タイプの変数で任意のメソッドを呼び出すようにします Nothing
とても奇妙だと思います。