Scalaの変位指定アノテーションと上限・下限境界がわからない
LL脳には辛い。
説明を読んでるときには、「なるほどなー」、と思うんだけど、いざ出てくると「どういう意味だっけ…」ってなるし、「いつ使えばいいんだ…」ってなってる。
classだけではなくて、defにも使えるので、混乱する。。。
とりあえずこれは理解した。
class Aaa class Bbb extends Aaa class Ccc extends Bbb class D[T >: Bbb] val dAaa = new D[Aaa] // dAaa: D[Aaa] = D@4b2bac3f val dBbb = new D[Bbb] // dBbb: D[Bbb] = D@4988d8b8 val dCcc = new D[Ccc] // error: type arguments [Ccc] do not conform to class D's type parameter bounds [T >: Bbb] class E[T <: Bbb] val eAaa = new E[Aaa] // error: type arguments [Aaa] do not conform to class E's type parameter bounds [T <: Bbb] val eBbb = new E[Bbb] // eBbb: E[Bbb] = E@2cd2a21f val eCcc = new E[Ccc] // eCcc: E[Ccc] = E@3514a4c0
上限境界と下限境界は、定義したクラスとかメソッドとかに渡す時にチェックするってことかな。
Scalaにおける表明
assert()
def add100(x: Int): Int = { val z = x + 100 assert(z >= 0) // 必ず0以上という表明 z }
ensuring()
def add100(x: Int): Int = { val z = x + 100 z ensuring(_ >= 0) } // ↑こう書けるので、↓こうも書ける def add100(x: Int): Int = x + 100 ensuring(_ >= 0)
assert()もensuring()も失敗すれば、java.lang.AssertionError例外が投げられる。
add100(-101) // java.lang.AssertionError: assertion failed
require()
前提条件のチェックにはrequire()が使える。
失敗すると、java.lang.IllegalArgumentException例外が投げられる。
def minus3(x: Int): Int = { require(x > 3) x - 3 }
minus3(2) // java.lang.IllegalArgumentException: requirement failed
Scalaで空のListにはreduceLeft()ではなくreduceLeftOption()を使用する
要素が存在するListにはreduceLeft()で問題ない。
List(123, 234, 345).reduceLeft{ (a, b) => a + b } //=> 702
でも要素が空っぽだと、エラーになる。
List[Int]().reduceLeft{ (a, b) => a + b }
// java.lang.UnsupportedOperationException: empty.reduceLeft
ググったらreduceLeftOption()なるものでOptionで包んで返してくれるので、これを使うようだ。
List[Int]().reduceLeftOption{ (a, b) => a + b } //=> Option[Int] = None List[Int]().reduceLeftOption{ (a, b) => a + b }.getOrElse(0) //=> 0 List(123, 234, 345).reduceLeftOption{ (a, b) => a + b } // Some(702) List(123, 234, 345).reduceLeftOption{ (a, b) => a + b }.getOrElse(0) // 702
ちなみに、この例のように、要素の値の和を出すためのメソッドのsum()がListにはあるけど、こちらも要素が空っぽだとエラーになるので、reduceLeftOption()を使うか、foldLeft()を使うとエラーにならないらしい(なぜだ)。
参考