技術のメモ箱

Scala/制御構文

制御構文

{}はブロック式と言い、最後に評価した値を返す


関数リテラル

(x: Int) => x + 1
args.foreach(arg => println(arg))  // 関数パラメータ、右矢印(=>)、関数本体で構成される。
args.foreach((arg: String) => println(arg))  // 関数パラメータの型を明示的に書く場合は、括弧が必要。
args.foreach(println)  // 関数リテラルが1個の引数を取る1文から構成される場合は、引数を明示的に指定しなくてよい

if式

最後に評価した結果を返す。3項演算子のように使える。
if式に限らず条件の括弧は必須。

if (x > y) x else y
val filename = if(!args.isEmpty) args(0) else "default.txt"

whileループ

while、do-whileがある。varを避けるのと同じようにwhileループも避けることが推奨されている。
意味のある値は得られない。結果値の型はUnit。

while (a != 0) { val temp = a; a = b % a; b = temp}
do { line = readLine(); println(line) } while (line!= "")

for式

for (arg <- args) println(arg)
val filesHere = (new java.io.File(".")).listFiles // カレントディレクトリのファイル・ディレクトリリスト
def fileLines(file: java.io.File) = scala.io.Source.fromFile(file).getLines().toList //ファイル読み込み
val forLineLengths = for {
    file <- filesHere if file.getName.endsWith(".scala") // フィルタリング
    line <- fileLines(file) // 複数ジェネレータを書くことでループを入れ子にできる
    trimmed = line.trim  // 束縛している。valが省略される
    if trimmed.matches(".*for.*")
} yield trimmed.length // yieldキーワードがあると配列を返す。この場合は条件にマッチした行数

try式

val harf = if (n % 2 == 0) n / 2 else throw new RuntimeException("n must be even")
try { val f = new FileReader("input.txt")
} catch {
    case ex: FileNotFoundException => // ファイルなしエラーを処理
    case ex: IOException => // その他のI/Oエラーを処理
} finally { file.close() } // 確実にファイルをクローズする
    def urlFor(path: String) = try { new URL(path) // try-catchは値を返す。finallyは返さない。
} catch { case e: MalformedURLException => new URL("http://www.scala-lang.org")

match式

friend match {
    case "salt" => "pepper"
    case "abc" | "def" => "or"
    case _ => "huh?"
}
val lst = List("A", "B", "C")
lst match {
    case List("A", b, c) => "最初がAなら後は何でもよい例。bとcはバインドされて変数として利用できる"
    case List("A", b, c) if b != "B" => "ガード式"
}

糖衣構文

プレースホルダー構文(場所を用意していることを示す記号)

1 + 2  // (1).+(2)と同じ。末尾が:でないメソッドは、左被演算子から呼び出す
1 :: twoThree  // twoThree.::(1)と同じ。末尾が:のメソッドは、右被演算子から呼び出す
numbers.filter(_ > 0) // (x: Int) => x > 0と同じ。
    // パラメータが一度しか使われないときのみ_を使える。2個めの_は第2パラメータを示す。
numbers.foreach(println _) // x => println(x)と同じ。(_)でもいい。
pagetop