Scala Cheet Sheets (Licensed by Brendan O’Connor under a CC-BY-SA 3.0 license)の和訳。

   
<h4 id="variables">変数 variables</h4>  
var x = 5 変数
Good val x = 5
Bad x=6
定数
var x: Double = 5 型を明示
<h4 id="functions">関数 functions</h4>  
Good def f(x: Int) = { x*x }
Bad def f(x: Int) { x*x }
関数の定義
隠れた誤り:Unitを返す関数になってしまっている
Good def f(x: Any) = println(x)
Bad def f(x) = println(x)
関数の定義
構文の誤り。関数定義の引数にはすべて型が必要
type R = Double 型に別名(alias)をつける
def f(x: R) vs.
def f(x: => R)
値呼び出し(call-by-value)
名前呼び出し(call-by-name) 遅延評価されるパラメータ
(x:R) => x*x 無名関数(anonymous function)
(1 to 5).map(_*2) vs.
(1 to 5).reduceLeft( _+_ )
無名関数:_ は 関数の引数に順々にマッチする
(1 to 5).map( x => x*x ) 無名関数で同じ引数を二度使う場合は、名前を付けなくてはならない
Good (1 to 5).map(2*)
Bad (1 to 5).map(*2)
無名関数:中置記法を使う。誤解を避けるには 2*_ を使うとよい。
(1 to 5).map { val x=_*2; println(x); x } 無名関数:ブロック記法では、最後の式の評価結果が返る.
(1 to 5) filter {_%2 == 0} map {_*2} 無名関数:ブロック記法のパイプライン (括弧記法でも使える).
def compose(g:R=>R, h:R=>R) = (x:R) => g(h(x))
val f = compose({_*2}, {_-1})
無名関数:複数のブロックを渡す。外側の括弧{}が必要.
val zscore = (mean:R, sd:R) => (x:R) => (x-mean)/sd カリー化(引数の一部を取り出した関数を作る)の平易な構文
def zscore(mean:R, sd:R) = (x:R) => (x-mean)/sd カリー化の平易な構文
def zscore(mean:R, sd:R)(x:R) = (x-mean)/sd カリー化の簡略構文。しかし、
val normer = zscore(7, 0.4)_ こちらの書き方では最後に_が必要で、部分関数(引数の一部に値を適用した関数)を作る
def mapmake[T](g:T=>T)(seq: List[T]) = seq.map(g) 汎用(generic)型
5.+(3); 5 + 3
(1 to 5) map (_*2)
中置記法の簡略
def sum(args: Int*) = args.reduceLeft(_+_) 可変長引数
<h4 id="packages">パッケージ packages</h4>  
import scala.collection._ ワイルドカード import.
import scala.collection.Vector
import scala.collection.{Vector, Sequence}
パッケージ内でクラスを(複数)選択してimport.
import scala.collection.{Vector => Vec28} クラスの名前を置き換えて import.
import java.util.{Date => _, _} java.utilからすべてimportするがDateは除く.
package pkg ファイルの先頭で
package pkg { ... }
パッケージを宣言
<h4 id="data_structures">データ構造 data structures</h2>  
(1,2,3) タプルの表記. (Tuple3)
var (x,y,z) = (1,2,3) 構造を分解して変数に束縛: タプルはパターンマッチで分解される.
Badvar x,y,z = (1,2,3) 隠れた誤り:各変数にタプル全体が代入される
var xs = List(1,2,3) リスト (immutable).
xs(2) 添字による要素へのアクセス. (slides)
1 :: List(2,3) cons.
1 to 5 以下と同じ 1 until 6
1 to 10 by 2
範囲指定の簡易構文
() (空の括弧) Unit型だけを受け取る関数引数の型 (C/Javaでいうvoid).
<h4 id="control_constructs">制御構造 control constructs</h4>  
if (check) happy else sad 条件分岐
if (check) happy same as
if (check) happy else ()
条件分岐の簡略
while (x < 5) { println(x); x += 1} whileループ
do { println(x); x += 1} while (x < 5) do whileループ
import scala.util.control.Breaks._
breakable {
for (x <- xs) {
if (Math.random < 0.1) break
}
}
break. (slides)
for (x <- xs if x%2 == 0) yield x*10 以下と同じ
xs.filter(_%2 == 0).map(_*10)
for文による網羅: filter/map
for ((x,y) <- xs zip ys) yield x*y 以下と同じ
(xs zip ys) map { case (x,y) => x*y }
for文による網羅: データ構造を分解パターンマッチしながら代入
for (x <- xs; y <- ys) yield x*y 以下と同じ
xs flatMap {x => ys map {y => x*y}}
for文による網羅: 直積 cross product を取る
for (x <- xs; y <- ys) {
` println(“%d/%d = %.1f”.format(x,y, x*y))<br>}`
for文による網羅: 命令型スタイル
sprintf-style
<h4 id="pattern_matching">パターンマッチ pattern matching</h2>  
Good (xs zip ys) map { case (x,y) => x*y }
Bad (xs zip ys) map( (x,y) => x*y )
caseを関数定義内で使う
Bad
val v42 = 42
Some(3) match {
case Some(v42) => println("42")
case _ => println("Not 42")
}
“v42” は任意のIntの値とマッチする変数名として解釈され、”42”が表示される.
Good
val v42 = 42
Some(3) match {
case Some(`v42`) => println("42")
case _ => println("Not 42")
}
”`v42`” のように`で囲むと、既に存在するval v42と解釈され、”Not 42”が表示される.
Good
val UppercaseVal = 42
Some(3) match {
case Some(UppercaseVal) => println("42")
case _ => println("Not 42")
}
大文字からはじまるUppercaseVal は既に存在するvalとして扱われ, 新しいパターン変数とは見なされない。UppercaseValに入っている値(42)は3と比較されるので、”Not 42”が表示される.
<h4 id="object_orientation">オブジェクト指向 object orientation</h4>  
class C(x: R) 以下と同じ
class C(private val x: R)
var c = new C(4)
コンストラクタの引数 - private
class C(val x: R)
var c = new C(4)
c.x
コンストラクタの引数 - public
class C(var x: R) {
assert(x > 0, "positive please")
var y = x
val readonly = 5
private var secret = 1
def this = this(42)
}

コンストラクタはクラスのbody.
publicメンバを宣言
値は取得できるが上書きできないメンバを宣言
privateメンバを宣言
代替コンストラクタ
new{ ... } 無名クラス
abstract class D { ... } 抽象クラスの定義 (生成できない)
class C extends D { ... } 継承したクラスの定義
class D(var x: R)
class C(x: R) extends D(x)
継承したときのコンストラクタの引数。 (本当は自動的にパラメータを親に引き継げるようになる用になってほしい)
object O extends D { ... } singletonを定義. (モジュールのように)
trait T { ... }
class C extends T { ... }
class C extends D with T { ... }
trait.
traitをインターフェースとして使い、実装を提供. コンストラクタの引数を取らない場合. mixin-able
trait T1; trait T2
class C extends T1 with T2
class C extends D with T1 with T2
複数のtraitを組み合わせる
class C extends D { override def f = ...} 宣言を上書きするときはoverrideを付ける
new java.io.File("f") オブジェクトを生成
Bad new List[Int]
Good List(1,2,3)
型の誤り:抽象型は生成できない
代わりに慣習として型を隠したfactoryを使う
classOf[String] classの情報を得る
x.isInstanceOf[String] 型があっているか検査 (実行時)
x.asInstanceOf[String] 型のキャスト (実行時)
x: String 型の記述によるチェック (コンパイル時)
comments powered by Disqus