最近Scalaを始めました。(函数型プログラミングと手続型プログラミングの良いとこ取りをできると聞いて)
以下覚え書きみたいな感じでこの数日で学んだことを書いていきます。
主にJavaを知っている人向けにJavaとの違いをメインに書きます。
今回は構文の話です。
構文
演算子
四則演算
Javaでは四則演算はint, long, doubleなどのプリミティブ型にしか使えませんでしたが、ScalaではBigInt(scala.math.BigInt, BigIntegerのScala版)などの型を持つ値に対しても使用可能になっています。またユーザーの定義する型についても自由に演算子を定義することが可能です。
1引数メソッドとの関係
Scalaでは四則演算を含む演算子はただの1引数のメソッドとして定義されており、例えば
a + b
という式は
a.+(b)
として解釈されます。逆に1引数のメソッドは(その名前が何であっても)中置記法の2項演算子として書くことができ、例えばBigIntのpowメソッドを呼び出す際に、
a pow 4
と書けば
a.pow(4)
と同じ扱いになります。
演算子の優先順序や結合性はその名前の最初の文字などによって決められており(例えばここを参照)、このためシフト演算子(<<)と比較(<)が同じ優先順序になるという面白いことが起きています。また、名前の最後の文字が":"のメソッドは右結合で、中置記法で書くと左右が逆になります。例えば
a :: b
は
b.::(a)
とみなされます(おそらく不変リストの定義のための仕様)。
宣言
変数
Scalaにはどこを参照するかを変更可能な変数と変更不可能な変数があり、それぞれvalとvarを使って定義します。例えば
val q : Int = 4 // q is of type Int and initialized with 4. The value of q cannot be changed.
や
var r : Int = 5 // r is of type Int and initialized with 5. One can modify the value of r by assignment (for example, "r = 3").
などと定義します。varで定義した方は例えば
r = 3
などとして値を変更することができます。
また、クラスのインスタンスを格納する変数をvalで定義した場合、どこを参照するかを変更することはできませんが、中身を変更することはできます。例えば
val arr = Array(1,2,3) // Initialized with an Int array with element {1,2,3}.
arr(0) = 4 // The first element becomes 4.
は正しくコンパイルできます。
クラス
Javaでは
public class AAA {
public int ff(int q) { /* ... */ }
}
だったのが、Scalaでは
class AAA {
def ff(q : Int) : Int { /* ... */ }
}
と書くことになります。(デフォルトでpublic)
staticメソッドは書けませんが、代わりにオブジェクトという、Javaでいうstaticメソッドしかないクラスを定義することができます。例えば、
object WW {
def gg(q : Int) : Int { /* ... */ }
}
で大体Javaの
public class WW {
public static int gg(int q) { /* ... */ }
}
と同じ意味です。
次は型システムと標準ライブラリについてです。