Scala

Scalaのざっくり入門

More than 1 year has passed since last update.


関数型のメリット


  • 副作用の排除


副作用とは

ある機能がコンピューターの(論理的な)状態を変化させ、それ以降で得られる結果に影響をあたえることをいう


  • 変数への値の代入

  • データ構造を直接変更する

  • オブジェクトのフィールドを設定する

  • 例外をスローする、またはエラーで停止する

  • コンソールに出力する、ユーザ入力を読み取る

  • ファイルを読み取る、ファイルに書き込む

  • 画面上に描画する


純粋関数

副作用を持たない関数


メリット


  • 宣言的な記述なため、簡潔に書けることが多く、関数の仕様を理解しやすい

  • 副作用がないため、形式的な証明がし易い

  • 関数の評価結果がコンテキストに依存しないため、テストがし易い

  • コンテキストに影響を与えないため、関数を組み合わせて利用しても相互に影響しない


インストール


scalaenvを使ったインストール


scalaenvのインストール

$ git clone git://github.com/mazgi/scalaenv.git ~/.scalaenv

$ echo 'export PATH="${HOME}/.scalaenv/bin:${PATH}"' >> ~/.bashrc
$ echo 'eval "$(scalaenv init -)"' >> ~/.bashrc


scalaのインストール

$ scalaenv install -l

$ scalaenv install scala-2.11.7
$ scalaenv versions


基本構文


コメント

// コメント

/* これもコメント */
/**
* コメントです
*/


セミコロン

セミコロン(;)は省略可能


変数

var 変数名:型 = 値

型については、型推論であるため省略可能

var num:Int = 1

var str:String = "abc"
var short:Short = _ // _で初期値が設定される


定数

val 定数名:型 = 値

val NUM:Int = 1

var STR:String = "abc"


代表的な型

name
description
default value

Boolean
真偽値
false

Char
2byte文字列
'\0'

String
文字列
null

Short
整数(16bit)
0

Int
整数(32bit)
0

Long
整数(64bit)
0

BigInt
任意精度整数
null

Fload
浮動小数(32bit)
0.0

Double
浮動小数(64bit)
0.0

BigDecimal
任意精度固定小数
null

Symbol
シンボル(文字の前にシングルクォート
null


制御文


if

if (true) 1 else 2


while

条件式はBoolean型である必要がある

while (true) A


for

for (s <- Array("a", "b", "c")) println(s)


match

他の言語でいわゆる、swich-case文のイメージ

var one = 1

one match {
case 1 => println("one")
case 2 => println("two")
case _ => println("other")
}


関数

def 関数名 (引数名 : 引数の型) : 戻り値の型 = {}

def append_ten(num : Int): Int = {

return num + 10
}

returnは省略可能で、省略した場合は最後に評価した式の値が戻り値として返される


戻り値の型と{}も省略可能

1行で記述

def append_ten(num : Int) = num + 10


クラス・メソッド


コンストラクタ

// class名(コンストラクタのパラメータを宣言)

class User(_name : String) {
def name = _name
}
var user = new User("Tom")
println(user.name) // Tom


フィールド

フィールドはvarvalで定義する


varではsetter/getterの提供、valではgetterのみの提供

class User(_name : String, _age : Int) {

var name = _name
val age = _age
}
var user = new User("Tom", 23)
println(user.name) // Tom
println(user.age) // 23
user.name = "Bob" // nameは"Bob"に更新される
user.age = 14 // val定義なのでエラーになる


アクセス修飾子と継承

class User(_name: String, _age: Int) {

val name = _name
val age = _age

def agree = println("Hi, I'm " + name)

def how_old = println("I'm " + fudge_the_count)

protected def real_age = age // protected メソッド

private def fudge_the_count = age - 5 // private メソッド
}

// extendsキーワードで継承
class Profile(_name: String, _age: Int) extends User(_name: String, _age: Int) {

// 親クラスのメソッドをオーバーライド
override def agree = println("Hi, I'm " + name + ". I'm going to be " + real_age + " this year")

}

var user = new User("Tom", 42)
user.agree
user.how_old

var profile = new Profile("Tom", 42)
profile.agree


オブジェクト

シングルトンオブジェクトの作成 = Javaのstaticと同等の役割


mainメソッド

実行時の処理を実装する

object Obj {

def main(args: Array[String]) {
println("Hello, World")
}
}


コンパニオンオブジェクト

クラス名と同じ名前をつけたオブジェクトのこと


共通の操作・処理を扱う

class Sample {

}

object Sample {
}


ファクトリー

class Sample private(a: Int) {

protected var n = a
}

object Sample {
def apply(a: Int) {
new Sample(a)
}
}

Sample.apply(123)
Sample(123)


トレイト(Trait)

機能の実装が行えるインタフェースのようなもの


Javaのインタフェースと同様、mix-inすることが出来る

trait Agree {

def en = println("Hello, World")
}

trait Body {
}

/* mix-in */
class User extends Agree with Body


タプル(Tuple)

複数のデータを格納できるコンテナ型。違う型でも格納できる。

val t = (1, "abc", 2)

22個までがタプルに格納できる限界数


コレクション


Seq

要素を並べて管理するコレクション

var seq = Seq(1, 2, 3)

// 取得
println(seq(0))
// loop
seq.foreach { println }


Map

キーを元に値を取得するコレクション

var map = Map("key" -> "val")

// 取得
println(map("key"))
// 追加
map += ("key2" -> "value")


例外処理

try {

func()
catch {
case e: IOException => ...
finaly {
}

try, catchはそれぞれ値を返すが、finalyは返さない


Option

Optionは値がない可能性を型で表現している

ScalaのOptionとEitherで例外処理を行う方法


スレッド

JavaのThread等そのまま使えるが、Actorを使うことが多いらしい

Scalaでアクター!


参考文献