型の階層構造
object Main {
def main(args: Array[String]): Unit = {
// すべての型は 4 つに大別できます (Null型, Nothing型を除く)
// Any <- AnyVal <- Unit,プリミティブ <- Nothing
// Any <- AnyRef <- String,その他のクラス <- Null <- Nothing
val i: Int = 123 // プリミティブ型
val void: Unit = () // Unit型 (値はある)
val str: String = "string" // 文字列
val obj: List[Int] = List(1,2,3) // その他のクラス (Option型なども含む)
// すべての型は Any を継承
println(i.isInstanceOf[Any]) //=> true
println(void.isInstanceOf[Any]) //=> true
println(str.isInstanceOf[Any]) //=> true
println(obj.isInstanceOf[Any]) //=> true
// すべての型は AnyRef または AnyVal のいずれかを継承 (AnyRef と AnyVal は Any を継承)
def func1: AnyVal = i
def func2: AnyVal = void
def func3: AnyRef = str
def func4: AnyRef = obj
println(func1) //=> 123
println(func2) //=> ()
println(func3) //=> string
println(func4) //=> List(1, 2, 3)
// Null型はすべての AnyRef の子クラスを継承。インスタンスは null のみ。
val myNull: Null = null
// val i2: Int = myNull // エラー
// val void: Unit = myNull // エラー
val str2: String = myNull
val obj2: List[Int] = myNull
// Nothing型はすべての型を継承。インスタンス化できない。本当に値がない型です。
def func5: Nothing = {
throw new Exception
}
}
}
比較演算
AnyRef 型の比較は ==
, !=
, eq
, ne
です。AnyVal 型の比較は ==
, !=
のみです。
object Main {
def main(args: Array[String]): Unit = {
// String 型は AnyRef 型を継承。Scala では以下は値の比較
println("abc" == "abc") //=> true
println("abc" != "ABC") //=> true
// 他の AnyRef 型に関する例
val obj1: List[Int] = List(1,2,3)
val obj2: List[Int] = List(1,2,3)
println(obj1 == obj2) //=> true (値は同じ)
println(obj1 != obj2) //=> false
println(obj1 eq obj2) //=> false (参照先は異なる; AnyRef に関しては eq が使用可能)
println(obj1 ne obj2) //=> true
// AnyVal 型に関しては eq/ne が存在しない
val i1: Int = 1
val i2: Int = 1
println(i1 == i2) //=> true
// println(i1 eq i2) // エラー: value eq is not a member of Int
}
}
==
,!=
→ 値を比較- Java における
str1.equals(str2)
等の処理に相当 (Java には否定の比較はなし)
- Java における
eq
,ne
→ 同じ参照先であるかどうかを判定 (参照の比較)- Java における
==
および!=
に相当
- Java における
暗黙の型変換 (implicit)
濫用するとコードが分かりにくくなることに注意して使用します。
object Main {
def main(args: Array[String]): Unit = {
// クラス定義
class MyClassA {
var prop: String = ""
def methodA: Unit = {
println("methodA")
}
}
class MyClassB {
var prop: Int = 0
def methodB: Unit = {
println("methodB")
}
}
// 暗黙の型変換を定義
import scala.language.implicitConversions // import が必要
implicit def myConverterFromMyClassA2MyClass2(objA: MyClassA): MyClassB = {
val objB = new MyClassB
objB.prop = objA.prop.size
objB
}
// myConverterFromMyClassA2MyClass2 が見えるスコープ内であれば変換される
val objA = new MyClassA
objA.prop = "string"
val objB: MyClassB = objA
println(objB.prop) //=> 6
objA.methodA //=> methodA
objA.methodB //=> methodB (暗黙の型変換のため実行できる)
}
}
似たような型/インスタンスの区別
型
Nothing
インスタンスを持てない、すべてのクラスのサブクラスUnit
唯一のインスタンス()
をもつクラス
インスタンス
null
Null 型の唯一のインスタンス (シングルトン)Nil
要素が空の List オブジェクトNone
無いことを表現する Option 型のインスタンス
0
記事の執筆者にステッカーを贈る
有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。
さらに詳しく →Feedbacks
ログインするとコメントを投稿できます。
関連記事
- Scala 文字列の処理書式指定 object Main { def main(args: Array[String]): Unit = { println("%d + %d = %d".format(1, 1, 2)) //=> 1 + 1 = 2 } } 文字列の比較 ヒアドキュメント 他の言語でいう「ヒアドキュメント」のようなものは """ で囲うことで実現できます。 object Main ...
- Scala 日付に関する処理Date クラスを文字列にフォーマット import java.util.Date object Main { def main(args: Array[String]): Unit = { // format は Date に限らない文字列用の機能です。 println("%d-%d-%d" format (1, 1, 1)) //=> 1-1-1 printl...
- 酢豚の基本的な使い方 (sbt)sbt は Scala および Java を主な対象としたビルドツールです。Scala Build Tool の略ではありませんが、Simple Build Tool という明示的な記述も公式ドキュメントなどには見当りません。以下 sbt の基本的な使用例をまとめます。使用した sbt のバージョンは 0.13 です。 公式ドキュメント [sbt 0.13](http://www.scala-sb...
- Scala 関数のサンプルコード「デフォルト引数」および「Unit 型を返す関数」 object HelloWorld { def main(args: Array[String]): Unit = { def myPrint(myArg: String = "default_value") = println(myArg + "!") val result = myPrint() //=> defau...
- Scala 組み込みの制御構造if-else 条件分岐で知られる if-else は三項演算子のようにも使用されます。 object HelloWorld { def main(args: Array[String]): Unit = { val myVal = if (!args.isEmpty) args(0) else "default" println(myVal) } ...