Scalaのざっくり入門


## 関数型のメリット
- 副作用の排除

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

- 変数への値の代入
- データ構造を直接変更する
- オブジェクトのフィールドを設定する
- 例外をスローする、またはエラーで停止する
- コンソールに出力する、ユーザ入力を読み取る
- ファイルを読み取る、ファイルに書き込む
- 画面上に描画する

### 純粋関数

副作用を持たない関数

#### メリット

- 宣言的な記述なため、簡潔に書けることが多く、関数の仕様を理解しやすい
- 副作用がないため、形式的な証明がし易い
- 関数の評価結果がコンテキストに依存しないため、テストがし易い
- コンテキストに影響を与えないため、関数を組み合わせて利用しても相互に影響しない
 
## インストール

### scalaenvを使ったインストール

#### scalaenvのインストール

```console
$ git clone git://github.com/mazgi/scalaenv.git ~/.scalaenv
$ echo 'export PATH="${HOME}/.scalaenv/bin:${PATH}"' >> ~/.bashrc
$ echo 'eval "$(scalaenv init -)"' >> ~/.bashrc
```

### scalaのインストール

```console
$ scalaenv install -l
$ scalaenv install scala-2.11.7
$ scalaenv versions
```

## 基本構文

### コメント

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

### セミコロン

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

### 変数

var 変数名:型 = 値
型については、型推論であるため省略可能


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

### 定数

val 定数名:型 = 値

```scala
val NUM:Int = 1
val 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       |
|Float|浮動小数(32bit)|0.0       |
|Double|浮動小数(64bit)|0.0      |
|BigDecimal|任意精度固定小数|null |
|Symbol|シンボル(文字の前にシングルクォート|null|

### 制御文

#### if

```scala
if (true) 1 else 2
```

#### while

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

```scala
while (true) A
```

#### for

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

#### match

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

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

### 関数

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

```scala
def append_ten(num : Int): Int = {
  return num + 10
}
```

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

1行で記述

```scala
def append_ten(num : Int) = num + 10
```

### クラス・メソッド

#### コンストラクタ

```scala
// class名(コンストラクタのパラメータを宣言)
class User(_name : String) {
  def name = _name
}
var user = new User("Tom")
println(user.name) // Tom
```

#### フィールド

フィールドは`var`か`val`で定義する  
`var`ではsetter/getterの提供、`val`ではgetterのみの提供

```scala
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定義なのでエラーになる
```

#### アクセス修飾子と継承

```scala
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メソッド

実行時の処理を実装する

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

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

クラス名と同じ名前をつけたオブジェクトのこと  
共通の操作・処理を扱う

```scala
class Sample {
}

object Sample {
}
```

##### ファクトリー

```scala
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することが出来る

```scala
trait Agree {
  def en = println("Hello, World")
}

trait Body {
}

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

### タプル(Tuple)
複数のデータを格納できるコンテナ型。違う型でも格納できる。

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

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


### コレクション

#### Seq

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

```scala
var seq = Seq(1, 2, 3)
// 取得
println(seq(0))
// loop
seq.foreach { println }
```

#### Map

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

```scala
var map = Map("key" -> "val")
// 取得
println(map("key"))
// 追加
map += ("key2" -> "value")
```

### 例外処理

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

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

#### Option

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

[ScalaのOptionとEitherで例外処理を行う方法](http://blog.shibayu36.org/entry/2015/08/31/103000)


### スレッド

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

[Scalaでアクター！](http://qiita.com/f81@github/items/55b83d7f4104b1a4dfac)


## 参考文献
- [Scala入門時に役立つ情報まとめ](http://qiita.com/nesheep5/items/49019b9df4836d36ec1f)