Scala
Scalaについて触ってみようと思い立ちました。
さしあたっては基本的なところとWebフレームワークを触るところまでを考えています。
参考: EclipseでScalaプログラミングを始めるための基礎知識 (2/3) - @IT
インストール
msiがあった。
C:\scalaにインストール。
環境変数の設定
PATHは通ってた。
REPL
C:\Users\qnzm>scala -version
Scala code runner version 2.9.2 -- Copyright 2002-2011, LAMP/EPFL
C:\Users\qnzm>scala
Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_22).
Type in expressions to have them evaluated.
Type :help for more information.
scala> println("Hello Scala World!!!!")
Hello Scala World!!!!
バージョンは2.9.2。
Scala IDE for Eclipse
eclipseはもともと入っていたので。
- [Help] > [Install New Software]
- Name: Scala IDE for Eclipse 2.0
- Location: http://download.scala-ide.org/releases-29/stable/site
全てインストール。
情報
- プログラミング言語Scala 日本語情報サイト
- 書籍: Scala実践プログラミング
とりあえず一通りのことを知って動くものを作るのには適しているかなと選択。
変数
- var : 再代入可。普通の変数
- val : 再代入不可。代入のことを「束縛(bind)」ということも。(関数型っぽい)
- 可能な限りvalを使うのが良い。
データ型
- ルートはAny型
- その下に値型AnyValと参照型AnyRef。
- 値型AnyValはプリミティブ型。
- Boolean
- Byte
- Short
- Char
- Int
- Long
- 参照型AnyRefはSystem.lang.Object相当。
- 文字列String
- List
- Map
- Unit(voidに相当)
比較
ヒアドキュメント
"""で囲むとエスケープシーケンスや改行もそのまま記述できる。
scala> var str = """aaa
| bbb
| ccc
| ddd"""
str: java.lang.String =
aaa
bbb
ccc
ddd
Symbolリテラル
識別子の前に「'」(クォート)を付けることで、その文字を表すSymbolリテラルになる。 Symbolリテラルは必ず同一。 比較が高速(同じオブジェクトを指しているかを見るのみだから) マップのキー等で活用。
XMLリテラル
整形式(well-formed)であることが保証される。「&」「<」「>」などの文字は自動で適切にエスケープされる。 XMLを使えば、エスケープ処理を気にしなくて良い。
scala> val title:String = "aaa"
title: String = aaa
scala> val html =
| <html>
| <head><title>{title}</title></head>
| <body>
| <h1>{title}{new java.util.Date}</h1>
| </body>
| </html>
html: scala.xml.Elem =
<html>
<head><title>aaa</title></head>
<body>
<h1>aaa Sat Oct 13 15:59:18 JST 2012</h1>
</body>
</html>
配列
javaと異なり、配列もオブジェクト。
scala> val arr:Array[Int] = Array(1, 2, 3, 4, 5)
arr: Array[Int] = Array(1, 2, 3, 4, 5)
scala> arr
res8: Array[Int] = Array(1, 2, 3, 4, 5)
scala> arr(2)
res9: Int = 3
List
線形リスト。不変データ構造。
scala> var lst:List[Int] = List(1,2,3)
lst: List[Int] = List(1, 2, 3)
scala> lst
res11: List[Int] = List(1, 2, 3)
scala> lst(2)
res12: Int = 3
Map
ハッシュ/連想配列/辞書型。デフォルトでは不変。
scala> val map = Map("a" -> 1, "b" -> 2)
map: scala.collection.immutable.Map[java.lang.String,Int] = Map(a -> 1, b -> 2)
scala> map
res13: scala.collection.immutable.Map[java.lang.String,Int] = Map(a -> 1, b -> 2)
scala> map("b")
res14: Int = 2
タプル
scala> (1, 2)
res15: (Int, Int) = (1,2)
scala> ("a", "b", "c")
res16: (java.lang.String, java.lang.String, java.lang.String) = (a,b,c)
scala> ("a", 1)
res17: (java.lang.String, Int) = (a,1)
制御構造
scala> if( i % 2 == 0 ) println("even") else println("odd")
even
scala> var cnt = 0
cnt: Int = 0
scala> while(cnt <= 5){
| println(cnt)
| cnt = cnt + 1
| }
0
1
2
3
4
5
scala> for( n <- 0 to 3){ println(n) }
0
1
2
3
scala> var xs = List(0,2,4,6,8)
xs: List[Int] = List(0, 2, 4, 6, 8)
scala> var ys = List(1,3,5,7,9)
ys: List[Int] = List(1, 3, 5, 7, 9)
scala> for(x <- xs; y <- ys; if x > 3; if y > 4) yield x + ":" + y
res24: List[java.lang.String] = List(4:5, 4:7, 4:9, 6:5, 6:7, 6:9, 8:5, 8:7, 8:9)
for文で、リスト内包表記が書ける。(Scalaでは、for内包表記と呼ばれている) for文の「一時変数 <- 配列etc」の部分はジェネレータ部と呼ばれ、;(セミコロン)区切りでいくつでも指定できる。
例外
パターンマッチに従い例外を捕捉。
scala> val n = try{ "99".toInt } catch { case e:Exception => -99 }
n: Int = 99
関数
scala> def foo(x:String):String = { x + ":" + x }
foo: (x: String)String
scala> foo("bar")
res27: String = bar:bar
- returnは書かない(式を評価した結果の値が、関数の結果)
- 括弧は省略可能
- ただし、副作用を伴うなら括弧を付けて宣言することが推奨されている
アンダースコアを末尾につければ、関数を取り出せる。 (関数はファーストクラスオブジェクト)
scala> val func = foo _
func: String => String = <function1>
scala> func("2")
res32: String = 2:2
関数を引数に取る、関数リテラル。
scala> def evenOrOdd( f:(Int) => Boolean, n:Int ) = {
| if( f(n) ) "even" else "odd"
| }
evenOrOdd: (f: Int => Boolean, n: Int)java.lang.String
scala> evenOrOdd( n => n % 2 == 0, 9)
res33: java.lang.String = odd
プレースホルダー構文(引数省略時、アンダースコアで引数を受け取る)
scala> evenOrOdd( _ % 2 == 0, 9)
res34: java.lang.String = odd
高階関数。
scala> def rep( n:Int ) = { (s:String) => s * n }
rep: (n: Int)String => String
scala> rep(2)("foo")
res37: String = foofoo
型推論
- 変数宣言での型指定
- 関数の返り値型の型指定
雑感
- 細かく気を配って綺麗で短い構文を心がけている印象。
- 関数型のエッセンスがなんだか懐かしい…最近触ってなかったからな、そういうの。
- はてなブログのMarkdown書きやすい。