トップ 差分 一覧 ソース 検索 ヘルプ RSS ログイン

Scalaの便利な機能

このエントリーをはてなブックマークに追加

[Scala]

Scalaの便利な機能

  listやmapなどのコレクションが便利

このへんの仕組みはRubyなどに見られる仕組みなのだが、List形式のデータを「.map/.foreach/.fold」でつないで形を変化させられる。だいたいは「.map」でどうにかなる。

// Listを作って中身を出力するとか
object prog {
    def main(args: Array[String]) = {
        val list = List(1,2,3,4,5)
        list.foreach ( 
            e => println(e)
        )
    }
}

// Javaだと
class prog {
    public static void main(String[] args) {
        int[] list = {1,2,3,4,5};
        for ( int i = 0; i < list.length; i++ ) {
            System.out.println(list[i]);
        }
    }
}

コレクションの処理を連結できる

object prog {
    def main(args: Array[String]) = {
        List(1,2,3,4,5).map ( 
            e => e * e
        ).foreach(println _)
    }
}

  パターンマッチが使える

パターンマッチは最近の言語に見られだした新しい仕様。これまでのC言語型の構文で、If文や正規表現を使っていた部分が大幅にこのパターンマッチによって綺麗に書けてバグを減らせる。

通常のパターンマッチ

  • 変数の右辺にmatchを置くとパターンマッチになる
  • 関数の返り値をパターンマッチすることもできる
object prog {
    def main(args: Array[String]) = {
        "Hello" match {
            case x:String => // case <変数>:型 => 
                println(x)
            case _ =>
                println("boo") 
        }
    }
}

関数の引数にパターンマッチ

  • 関数リテラルでfuncを定義、その内部でパターンマッチをしている
object prog {
    def main(args: Array[String]) = {

        val func: String => Boolean = {
            case "Hello" =>
                true
            case _ =>
                false
        }

        println(func("Hello"))
        println(func("World"))
    }
}
  • これは例えばfoldの内部でパターンマッチを使う場合などに有用
import scala.util.Either
import scala.util.Right
import scala.util.Left

object prog {
    def main(args: Array[String]) = {

        val func: String => Either[Boolean, Boolean] = {
            case "Hello" =>
                Right(true)
            case _ =>
                Left(false)
        }

        println(func("Hello").fold(
            x => x,
            {
                case true =>
                    "World"
                case false =>
                    "not World"
            }
        ))
    }
}

  豊富なOption

Either[type, type] のような書き方をすることで、コード量を減らせそう
以下はEitherを使った処理の一例
object prog {
    def main(args: Array[String]): Unit = {
        println("Hello")

        val result = (for {
            r <- func2().right
            r <- func1().right
        } yield r)

        println(result)
    }

    def func1(): Either[String, Boolean] = {
        println("func1")
        Right(true)
    }

    def func2(): Either[String, Boolean] = {
        println("func2")
        Left("This is error")
    }
}

  再帰関数の最適化ができる

いろいろ使用条件はあるようだが…

  リソースの保持と開放

Pythonのwith構文のようなもの

お名前: コメント: