【入門編】基礎から学ぶScala①:型とアノテーション、変数

言語学習

Scalaの学習の第一歩として、Scalaにおける型の基礎と、変数の定義・型アノテーションについて学んでみました。

JavaScriptやRustのように、再代入可能な変数と再代入不可能な変数を明示的に分けて記述することができます。

Scalaの型階層構造

プログラミング言語では型は階層構造で示すことができます。

Scalaの場合は、下図のような階層構造をなしており、Anyという型をトップとして、文字列・数値などの型がそのサブタイプとして定義されています。

Any

Any型は、Scalaで扱うあらゆる型のスーパータイプとなる型で、トップ型とも呼ばれます。

あらゆる型のスーパータイプなので、あらゆる値を割り当てることができますが、静的型付けの利点を損なうリスクが大きいのであまり使わない方が得策。

var anyVal: Any = 123
println(anyVal)        // 123
anyVal = "Test"        // 数値の入っていた変数に文字列を代入可能
println(anyVal)        // "Test"

AnyVal, AnyRef

AnyValはAnyの直下に位置するサブクラスです。

Javaでいうところのプリミティブ型相当の型ですが、Scalaにはプリミティブ型は存在せず、真偽値なども含めてすべてオブジェクトになっています。

また、AnyRefも同様にAnyの直下に位置しており、こちらは参照型を意味しています。

AnyVal以外の型やユーザー定義型はすべてAnyRefのサブタイプとなります。

var anyVal: AnyVal = 1.234
anyVal = ()
anyVal = false
anyVal = 'a'
// anyVal = "Hello"   // 文字列の代入はエラー
// anyVal = List()    // AnyValにAnyRefのサブタイプは代入できない

var anyRef: AnyRef = List()
anyRef = Some("Test")
anyRef = null
// anyRef = 123       //  AnyRefにAnyValのサブタイプは代入できない

Nothing, Null

Nothingは上記のあらゆる型のサブタイプとなる型でボトム型と呼ばれます。

TypescriptでいうところのNever型ですね。

Nullはすべての参照型、つまりAnyRef型のサブタイプです。

JVM言語との相互運用のために用意されている型で、Scalaのコード内ではあまり使われるべきではないそう。

Javaのプリミティブ相当の型

object TypeAndAnnotations extends App {
  val bool: Boolean = false
    val str: String = "Hello"
    val char: Char = 'a'
    val byte: Byte = 127
    val short: Short  = 32767
    val int: Int = 2147483647
    val long: Long = 9223372036854775807L
    val float: Float = 2.0f
    val double: Double = 3.14
    val unit: Unit = ()
    val nl: Null = null
    val lst: List[String] = List("Hello", "Scala")
    val opt: Option[String] = Some("Some")
}
型名概要
Boolean真偽値true, false
String文字列
ダブルクォーテーション(””)で囲う
“Hello World”
Char16ビット符号なしUnicode文字
シングルクォーテーション(”)で囲う
‘a’
Byte8ビット符号付き整数127, -128
Short16ビット符号付き整数32767, -32768
Int32ビット符号付き整数2147483647, -2147483648
Long64ビット符号付き整数9223372036854775807L
Float32ビット浮動小数点数2.0f
Double64ビット浮動小数点数3.14

変数定義とアノテーション

すでにコードに記載していますが、Scalaでは変数定義にvalとvarキーワードを用います。

それぞれの役割は以下のような感じ。

  • val : 再代入を許可しない変数の定義。Scalaのコードにおいてはなるべくこちらを使った方がよい
  • var : 再代入可能な変数の定義。

変数定義時の型アノテーション

基本的には、コンパイラーがコンパイル時に型を推論してくれるため、明示的に型アノテーションをつける必要はない場合が多い。

val str: String = "Hello Annotation"
val str = "Hello Annotation"  // 型アノテーションなしでもString型に推論してくれる
val strList = List("This", "is", "a", "list") // List[String]型に推論してくれる

まとめ

  • Scalaの型はAny型をトップ、Nothing型をボトムとした階層構造になっている
  • Scalaではあらゆる型がオブジェクトでJavaのプリミティブ相当の型はない
  • コンパイラが賢いので型のアノテーションは不要なことが多い

今回はScala学習の第一歩ということで軽めの内容でした。

次回は、条件分岐やループなどの制御構文を取り上下ていきたいと思います。

コメント

タイトルとURLをコピーしました