Perl日記

日々の知ったことのメモなどです。Perlは最近やってないです。

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()を使うとエラーにならないらしい(なぜだ)。



参考