あるプログラマの日記

プログラマのメモ、出来事、考えたこと、勉強とかの雑記

シンボル、タプル、Option

シンボル

  • シンボルは文字列のかわりに、マップのキーとして使われる事が多い。
  • シンボルは同じ名前の場合はメモリ上で同じオブジェクトを指す。
  • シンボルリテラルはシングルクォート(')の後に文字で始まりその後、0個以上の数字か文字が続く。
scala> 'foo
res0: Symbol = 'foo

scala> val bar = Symbol("foo")
bar: Symbol = 'foo

scala> bar == 'foo
res1: Boolean = true

scala> Symbol(" foo bar ")
res2: Symbol = ' foo bar

タプル

  • 2つ以上の項目を持つグループ。
  • 丸括弧 () 内にカンマで区切って項目を並べたもの
  • それぞれの項目は互いに無関係なので、違う型を混在させても型を一致させてもよい。
  • タプルのインスタンスはイミュータブル(変更不可)
  • タプルのリテラルは、scala.TupleNのインスタンス(N は 1〜22 で項目数を表す)
  • タプルの各要素には、タプル._1 .. タプル._N で参照できる。
  • タプルを代入する時は直接、変数を指定して展開することもできる。
scala> val tp1 = (1, "foo", true)
tp1: (Int, java.lang.String, Boolean) = (1,foo,true)

scala> tp1._1
res3: Int = 1

scala> tp1._2
res4: java.lang.String = foo

scala> tp1._3
res5: Boolean = true

scala> val (a, b, c) = tp1
a: Int = 1
b: java.lang.String = foo
c: Boolean = true

タプルの定義方法のいろいろ

scala> Tuple2(3, 7.8)
res6: (Int, Double) = (3,7.8)

scala> Pair(3, 7.8)
res7: (Int, Double) = (3,7.8)

scala> 3 -> 7.8
res8: (Int, Double) = (3,7.8)

Unit は java の void と同じような意味で使用されるが実体は項目のないタプル ()

scala> def foobar = { println("foobar") }
foobar: Unit

scala> () equals foobar
foobar
res9: Boolean = true

Option, Some, None

  • java は参照オブジェクトがない場合 null で表すが、Scala は Optionタイプを使用することを推奨。
  • Scala では参照オブジェクトがない場合 Option のサブクラスのオブジェクト None を使用する。
  • None は1つのオブジェクトとして存在すればよいので object で宣言されている。

Map に登録されていないキーを指定すると None が返され、存在するキーを指定するとキーに
対応する要素をもつ Some が返される。

scala> val map = Map(1 -> "one", 2 -> "two", 3 -> "three")
map: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> one, 2 -> two, 3 -> three)

scala> map.get(2)
res10: Option[java.lang.String] = Some(two)

scala> map.get(4)
res11: Option[java.lang.String] = None
  • Some の get は持っている値を返す。
  • Some の isEmpty は false を返す。
  • None の isEmpty は true を返す。
  • None で get を使用すると NoSuchElementException を投げる。
  • getOrElse は Some の場合は持っている値を返し None の場合は引数で指定したデフォルト値を返す。
scala> map.get(2).get
res11: java.lang.String = two

scala> map.get(3).getOrElse("none")
res12: java.lang.String = three

scala>  map.get(5).getOrElse("none: five")
res13: java.lang.String = none: five

scala> val op1 = Option("bar")
op1: Option[java.lang.String] = Some(bar)

scala> val op2 = Option(null)
op2: Option[Null] = None

scala> op1.isEmpty
res14: Boolean = false

scala> op2.isEmpty
res15: Boolean = true

scala> op1.get
res16: java.lang.String = bar

scala> op2.get
java.util.NoSuchElementException: None.get
        at scala.None$.get(Option.scala:275)
        at scala.None$.get(Option.scala:273)
..snip..

Map のキーに対応する値として null も指定できる。
Map にキーを指定して Some から null を取り出すこともできる。

scala> val map2 = Map(1 -> "one", 2 -> "two", 3 -> null)
map2: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> one, 2 -> two, 3 -> null)

scala> map2.get(3)
res17: Option[java.lang.String] = Some(null)

scala> val s = map2.get(3).get
s: java.lang.String = null