Perl日記

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

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



参考

Scalaで標準入力を受け取る

text1.txt

123
234 345 456
5
6
7
8
9
10

上のデータが標準入力でわたってくるので、受け取りたい。

Main.scala

object Main extends App {
  import scala.io.StdIn.readLine

  // 1行目
  val firstArg = readLine().toInt

  // 2行目をスペースで区切りながらIntにしてList化
  val Seq(secondArg1, secondArg2, secondArg3): Seq[Int] = readLine().split(" ").map(_.toInt).toList

  // 残りの行を一気にIntにしてList化
  val restArgs: List[Int] = Iterator.continually(readLine()).takeWhile(_ != null).map(_.toInt).toList


  println("firstArg: %d".format(firstArg))
  println("secondArg 1: %d, 2: %d, 3: %d".format(secondArg1, secondArg2, secondArg3))
  println("restArgs: %s".format(restArgs.mkString(",")))
}

実行

$ scalac Main.scala && cat text1.txt | scala Main
firstArg: 123
secondArg 1: 234, 2: 345, 3: 456
restArgs: 5,6,7,8,9,10