Scalaはじめました〜その1

　まあ、playはじめましたと変わらないんだけど。
チュートリアルはとりあえず「playだけ」を学びたかったんで、Javaでやりました。経験上、これもこれも必要だから同時にやっちゃおう！というのは往々にして失敗するので。「英語も大事なので、○○の勉強は英語のテキスト使おう」みたいな。結局コストかかってやんなくなるという……。
　まあ器用な人はできると思うけど……。僕はできそうにないので一個一個不器用なりに着実にやっていきましょう。

　次こそ本命のScalaに。
　今回は勉強に[コレ](http://www.atmarkit.co.jp/fjava/index/index_scala.html)使いました。

# Scalaの構文とか色々
　しばらく特筆すべきことがない……。普通の言語と同じなとこはガンガン飛ばして行って、ここをメモ代わりに使っていこう。

　糖衣構文の箇所が面白かったです。配列の要素指定に()を使う話です。あの()って、applyやらupdateやらと同じらしく。

```Scala
scala> val num = a2(1) //配列の要素を取得
num: Int = 2

scala> a2 //配列内容を表示
res25: Array[Int] = Array(100, 2, 3)

scala> a2(1) //値の取得
res31: Int = 2
 
scala> a2.apply(1) //値の取得
res32: Int = 2
 
scala> a2(1) = 10 //値の設定
 
scala> a2.update(1,10) //値の設定
```

a(0)はArrayに定義されてるapplyメソッドの呼び出し。
a(0)=10はArrayに定義されているupdateメソッドの呼び出し。

この()の要素指定がapply/update呼び出しの糖衣構文(シンタックスシュガー)といい、読み書きのしやすさのために導入される構文。

シンタックスシュガー！！かっこいい！

響きが気に入りました！しばらくなんとかの一つ覚えのように使う。

## Scalaの演算子

Scalaでは演算子は全てメソッド。

```Scala
scala> 1 + 2
res8: Int = 3
 
scala> 1 .+(2) //1の後に「.」を付けると、Doubleと判断されるので、スペースを入れる
res9: Int = 3
```

Scalaはメソッドが一つの引数を取る場合、ピリオドと()を省略できる。だからメソッド呼び出しが演算子のように見える。

おもしろい！

演算子はJavaと同じ。ただインクリメントとデクリメントは無い。+=と-=を使う。

## コレクション

Scalaの代表的なコレクションを勉強していく。JavaだとArrayList, HashMapさえありゃーどうにかなったけど、Scalaではどうだろう。

### リスト型
Listは先頭項目の追加/削除が高速だが、ランダムアクセス(添字を使用した要素へのアクセス)が遅い。<font color="red">先頭から順番に任意に処理していくのに向いている。</font>

ただ、Listを使ってしまうとList型は不変コレクションだから一度定義すると変更できない。変更がある場合はListBufferを使用する。

あと、List型は::メソッドを持っている。要素同士の結合を意味する。

```Scala
scala> val list1 = Nil
list1: scala.collection.immutable.Nil.type = List()
 
scala> val list2 = "Scala" :: list1
list2: List[java.lang.String] = List(Scala)
 
scala> val list3 = "Java" :: list2
list3: List[java.lang.String] = List(Java, Scala)
```

headメソッドとtailメソッドでListの先頭と、先頭を除く要素のListを返す。

### マップ型
連想配列、HashMap。こんな感じで宣言する。

```
Map[キーの型,値の型](キー1->値1, キー2->値2, ...)
```

実際のコードではこんな感じ。

```Scala
scala> val map = Map[String,Int]("Scala"->1,"Java"->2,"Ruby"->3)
map: scala.collection.immutable.Map[String,Int] = Map(Scala -> 1, Java -> 2, Ruby -> 3)
```

値取り出しは()でキーを指定する。 **シンタックスシュガー**ですね。

```
scala> m("Scala")
res50: Int = 1
```

mapで使用するメソッド表。

|メソッド|説明|
|:--|:--|
|empty|空のmapを返す|
|+|指定したキーと要素のペアを追加したmapを返す|
|-|指定したキーの要素を抜いたmapを返す|
|size|mapのサイズを返す|
|KeySet|キーのセットを返す|
|values|mapの値をiterableで返す|

おお、iterable！やっぱiteratorあるよね。よかった。

###タプル型
異なる要素を格納可能なList？かな。値をカンマで区切り()で囲んで定義する。ただ、要素の取得が特殊で、_1みたいに(アンダースコアと取得したい要素のindex)指定すればアクセスできる。こんな感じ。

```Scala
scala> val t1 = ("Scala",10)
t1: (java.lang.String, Int) = (Scala,10)
 
scala> val t2:Tuple2[String,Int] = ("Java",20)
t2: (String, Int) = (Java,20)

scala> val t = ("Scala",10,100.0d)
t: (java.lang.String, Int, Double) = (Scala,10,100.0)
 
scala> t._1
res71: java.lang.String = Scala
 
scala> t._2
res72: Int = 10
```

## for文
for文は普通とちょっと違う。Scalaにインクリメントは無いので、ちょっとiterator的な書き方になる。

```
for ([ジェネレータ] [フィルタ]*無くてもいい) 式
```
ジェネレータ部分はitem<-listItems的な感じで、iterator的というか、for each的に書く。

ListItemから要素を取り出し、printで出力するソース

```Scala
scala> val listItems = List("Scala","Java","Ruby")
listItems: List[java.lang.String] = List(Scala, Java, Ruby)
 
scala> for(item <- listItems) println("item = " + item)
item = Scala
item = Java
item = Ruby
```

for文でうんたんし結果を保持したい場合もある。そのときはyieldを使用する。

```
scala> val resultList = for(item <- listItems) yield "I use " + item
resultList: List[java.lang.String] = List(I use Scala, I use Java, I use Ruby)
 
scala> resultList
res33: List[java.lang.String] = List(I use Scala, I use Java, I use Ruby)
```

Scalaのfor文はいろいろ多機能で、yieldの他にも色々あるっぽい。

### 例外処理
```Scala
try {
	式
} catch {
	case 変数:例外クラスの型 => 例外処理の式
	......
} finally {
	式
}
```

実際のコードだとこんな感じ？

```Scala
scala> val result = try {
     |   "a".toInt
     |  } catch {
     |   case e:NumberFormatException => {
     |     println("exception!")
     |     -1
     |  } finally {
     |     println("finally!")
     |  }
exception!
finally!
result: Int = -1
```

例外処理はthrowを使用する。

```
scala> throw new Exception("throw Exception!")
java.lang.Exception: throw Exception!
	at .<init>(<console>:8)
……
```

### match
　Javaでいうswitch。break書かなくてもおｋ。default処理は_ => 式。以上。
　あー、あと条件式を型で記述できる。case i:Int　みたいな。


### 関数
おおお。関数型言語の関数。本題か。

関数型言語とは関数をファーストクラスオブジェクト(関数を引数や戻り値にできる)として扱えることを利用し、副作用を持たない関数を使用してプログラムを構築する手法。

「副作用を持たない」ってのはその関数の持つ変数とかに意図しない変更が起きないように、らしい。
なんで関数をファーストクラスオブジェクトとして扱えることが副作用がないとできるんだろう。という疑問を持って勉強する。

関数はdefで宣言する。

```
def 関数名[型パラメータ](引数名:引数の型名,...):返り値=関数本体
```

int型の引数を2つ取り、Int型を返す「add」という関数を定義してみる。

```Scala
scala> def add(x:Int, y:Int):Int = x + y
add: (x: Int, y: Int)Int
```
こんな感じで、値を返すときにreturnはいらない(別につけてもいい)。
あ、あとvoidを使いたいならunitとすればよい。

次に、関数を引数としてとる関数を定義する。

```Scala
scala> def calc(f:(Int,Int)=>Int, num:Int) :Int =f(num,num)
calc: (f: (Int, Int) => Int, num: Int)Int
 
scala> calc((x,y) => x + y,10)
res13: Int = 20
```

もちろん事前に関数を定義してそれを渡すこともできる。

```Scala
scala> val add = (x:Int, y:Int) => x + y
add: (Int, Int) => Int = <function2>
 
scala> calc(add, 10)
res14: Int = 20
```

### 高階関数
返り値に関数オブジェクトを返す関数を定義する。getFuncという関数を定義する。ちなみに仕様は以下。
引数:String
戻り値:「引数:Int,Int 戻り値:String」な関数

```
scala> def getFunc(str:String): (Int,Int)=>String = (x:Int, y:Int) => str + (x + y)
getFunc: (str: String)(Int, Int) => String
 
scala> val f = getFunc("result is ")
f: (Int, Int) => String = <function2>
 
scala> f(1,2)res17: String = result is 3
```

うう、ここらへん慣れないなー。=>とか=とか。まあ、腕動かして、腕に覚えさせるしかないね。

### クロージャ
その関数のスコープにおける引数意外の変数を参照できる関数。getterで取るなどして直接値をいじるんじゃなくて関数内で閉じる。カプセル化として重要。以下の感じ。

```Scala
scala> def counter() = {
     |   var count = 0
     |   () => {
     |     count += 1
     |     count
     |   }
     | }
 
counter: ()() => Int

scala> val c1 = counter()
c1: () => Int = <function0>
 
scala> c1()
res50: Int = 1
 
scala> c1()
res52: Int = 2
```

counter関数は「インクリメントする関数」を返す。だから() =>見たいな妙な書き方をしている。関数型では最後に評価された式を返すから、counter()で最後に評価された式は() => {...}となる。これは()メソッドを返す。=>{の中を見てみるとインクリメント...って寸法。

###クラス生成
ホントはコンストラクタとかthisとかいろいろごちゃごちゃ書かれてたんだけど、「言語を一つ持ってて、その言語を使ってコーディングするプログラマクラス」の例を一個あげてそれで終わる。

```Scala
scala> class Programmer(val language: String) {
     |		/** コンストラクタ **/
     |     println("Programmerインスタンスを生成します")
     |     println("language = " + language)
     |   	
     |   	/**引数がnullだったらエラー。「引数なし」はいいけど、nullはだめ。**/
     |   	require(_language != null)
     |     /** 補助コンストラクタ */
     |     def this() = this("Scala")
     |   
     |     def coding() = println(language + "を使ってコーディングします")
     | }
defined class Programmer

scala> val programmer1 = new Programmer
Programmerインスタンスを生成します
language = Scala
programmer1: Programmer = Programmer@1852a3ff

scala> val programmer2 = new Programmer("Java")
Programmerインスタンスを生成します
language = Java
programmer2: Programmer = Programmer@628c4ac0

scala> programmer
programmer1   programmer2

scala> programmer1.coding
Scalaを使ってコーディングします

scala> programmer2.coding
Javaを使ってコーディングします
```

このサンプルありゃあだいたいわかるよね。あと、thisはJavaと同じような使い方もできるよ。

### アクセス修飾子
Scalaのアクセス修飾子は注意。アクセス修飾子をつけなかったらなんと **publicになる**。Javaみたいに「修飾子なし」という修飾子にはならない。privateはあるよ。

### オーバーロード
あるよ！

### シングルトン
Scalaのシングルトンはすごい簡単。Javaだとprivateとstaticでゴニョゴニョするんだけど、Scalaならclass修飾子の代わりにObject修飾子をつけるだけ。わかりやすい！そりゃあnewできないよね。classじゃなくてobjectだし。そりゃあ一個しか実態もたないよね。classじゃなくてobjectだし。

と、とりあえずその1はここらへんで終わっとくか。キリがなさげ。また気が向いたらScalaの勉強再開します。しばらくはplayに夢中になっとくかーーーー。