Ari-Press

エンジニアAriのブログ.

はじめてのScala

最近Scalaを触っているのですが,なかなかに奥が深い.

いや,どの言語もそうなんだろうとは思うんですが,オブジェクト指向どっぷりな自分としては関数型の考え方がなかなか染み込まず...

というわけで,ちまちまと触っていた成果をまとめていこうかと思います.

最初にちょっと戸惑ったのは「関数を渡す」発想.具体的には以下のコードのようなもの.

1
2
'Hello, Scala!!'.toList.map(c => print(c))
println

「()」が省略できたりはLLっぽい書き方ですね.

このコードで最初理解しづらかったのは「〜.map(c => print(c))」の部分.

「Hello, Scala!!」の文字を一文字ずつ取り出して変数cに代入し,渡している「print(c)」を実行するイメージですね.

ちなみにこれは以下のような書き方もできます.

1
2
'Hello, Scala!!'.toList.map(print)
println

これは省略というかprint関数の引数に各要素がたまたま一致するからというイメージです.

上に書いたものは自分で無名関数を定義していて,こちらは元からある関数をそのまま渡しています.まあどっちでもいいですね.

そんな感じで勉強中のScalaを使って軽ーいユーティリティ的なものを一つ書いてみました.

1
2
3
4
5
6
7
8
9
10
11
12
package ari.obj

import java.io.File

object FileSeeker {
  def seek(file:File = new File('.'), pattern:String = '.*'): List[File] = file match {
    case f: File if f.isDirectory =>
      f.listFiles.toList.flatMap(t => seek(t, pattern))
    case f: File if pattern.r findFirstIn f.getPath isDefined => List(f)
    case _ => List()
  }
}

完全にそこらにありふれている,再帰を利用したフォルダ探索を「java.io.File」というJavaのクラスを利用して作ってみました.

処理としては渡されたFile型のfileがディレクトリであれば再帰的に探索し,ファイルでかつファイル名がパターンに一致するものであればリストとして返し,その他であれば空リストを返す...というような感じです.そのままですね.

Scalaはmatch処理がなかなか重要らしく,この辺の勉強も含めて書いてみました.型のマッチング(Option型が便利!この辺は追々・・・)やガード条件(if)など,応用の効く機能がたくさんありそうです.

この処理もJavaであればもうちょっと行数いくかな?と思うので,やはりScalaは生産性いいのでしょうね.

慣れれば・・・!