1. 概要

プログラミング言語を学ぶときは、その言語の基本的な型システムから始めるのが常に良いことです。 この記事では、Scalaの型階層について説明します。 Any AnyVal AnyRef Null 、およびNothingの基本について説明します。

2. Scalaのクラス階層

Scalaは静的に型付けされた言語であり、より優れた高性能のコードを作成するためのオプションを提供します。 JVMはコンパイル時にタイプをチェックし、実行時のパフォーマンスを向上させるためにコードを最適化します。 ScalaはJavaのようなプリミティブ型をサポートしておらず、非常に広大で多様な型システムを持っています。 次の図に示すように、Scalaのいくつかの重要な高レベル型クラスについて説明します。

2.1. 任意

ScalaにはクラスAny、があり、これは型階層の最上位にあります。 型システムのルートクラスです。 言い換えれば、Scalaの他のすべてのクラスは、明示的または暗黙的にAnyクラスの子です。

Any クラスで定義されているいくつかの標準メソッドがあります。たとえば、 equals hashCode toString は、デフォルトですべてのオブジェクトにアクセスできます。 Scalaで。 任意のクラスには、 AnyVal(値クラス) AnyRef(参照クラス)の2つのサブクラスがあります。 たとえば、Anyタイプの引数を取る関数anyを定義しましょう。

def any(value: Any): String = ""

次に、 Any型引数を関数any:に渡します。

assert(any(1) == "")
assert(any(true) == "")
assert(any(()) == "")
assert(any("S") == "")
assert(any(null) == "")
assert(any(List()) == "")

関数any、にさまざまなタイプの引数を渡しました。これは、Anyタイプの引数と互換性があります。

2.2. AnyVal

AnyVal classは、Scalaのすべての値型のルートクラスであり、Anyクラスの子です。 Scalaには、 Byte Short、Char、Int、Long、Float、Double、 Boolean、Unit。の9つの値クラスがあります。 ]最も重要なことは、すべての値クラスが abstract finalタイプであるということです。

さらに、Scalaの値型は、 Unit classを除いて、Javaのプリミティブ型に似ています。 Unit クラスは、JavaのVoidタイプに似ています。 Unit クラスの場合、インスタンス値()を1つだけ持つことができます。 したがって、Unitクラスをnewキーワードでインスタンス化することはできません。 つまり、Scalaの値型に割り当てることができるのはリテラル値だけです。 たとえば、AnyValタイプのパラメーターを受け取る関数anyValを以下に定義しましょう。

def anyVal(value: AnyVal): String = ""

次に、 AnyValタイプの引数を関数anyVal:に渡します。

val unit: Unit = ()
assert(anyVal(unit) == "")
val int: Int = 12
assert(anyVal(int) == "")
val bool: Boolean = false
assert(anyVal(bool) == "")

特に、関数anyValAnyValタイプのリテラル引数と互換性があることがわかります。 AnyVal型以外の引数を渡すと、コンパイラは文句を言い、メッセージエラーを生成します:型の不一致が必要です:AnyVal。

2.3. AnyRef

AnyRef は、Scalaのすべての参照型のルートクラスであり、Scala型システムのAnyクラスの子です。 これはJavaのObjectクラスに似ており、新しいキーワードを使用して参照クラスをインスタンス化できます。 最後に、Scalaは、Javaクラスを含むすべての参照クラスに適応できます。 たとえば、 AnyReftypeの引数を取る関数anyRefを定義しましょう。

def anyRef(value: AnyRef): String = ""

次に、クラスPersonを以下に定義しましょう。

case class Person(name: String)

参照型の引数を関数anyRefに渡してみましょう。

assert(anyRef(new Person("Same")) == "")

結論として、関数 anyRef は任意の参照型に適しており、非参照型には適していません。 非参照型をanyRef関数に渡すと、コンパイラはエラーメッセージエラーを発生させます:型の不一致が必要です:AnyRef。

2.4. ヌル

階層では、Nullクラスがすべての参照型の最下部にあります。 一般に、 Null 参照は、型システムの AnyRef タイプに割り当てることができますが、AnyValタイプには適していません。 Null クラスは、すべての参照クラスの子です。 説明のために、以下の同じ関数anyRefを見てみましょう。

assert(anyRef(null) == "")

結論として、nullリテラルをScalaの任意の参照クラスに割り当てることができます。

2.5. なし

Nothing は、Scalaタイプ階層のNullを含むすべてのタイプの子です。 通常、値はなく、変数に割り当てることもできず、 Nullとは異なります。つまり、名前が示すように、Nothingは何も意味しません。 以下の例を見てみましょう。

val list: List[Nothing] = List()
assert(list == List())

上記の例では、値をとらないリストを定義しました。

3. 結論

この記事では、Scala型システムの基本とScala型クラス間の関係について説明しました。 結局、完全なソースコードはGitHubにあります。