ちいさな引き出し

お宝からガラクタまで

Scalaのメソッドの定義

メソッドの定義

Scalaでメソッドを定義するには、defキーワードを使います。

def メソッド名(仮引数名: 仮引数の型): 戻値の型 = 関数処理
  • 戻値の型は省略可能です。型推論という機能がありコンパイラが型を自動で判定します。
  • 関数の最後にreturnは一般的に省略します。関数の最後の値がそのまま戻り値になります。
  • 仮引数はカンマで区切ることで複数指定できます。
  • 仮引数の型は省略できない。
  • 関数本体の{}は式が一つであれば省略可能
  • 引数がない場合は()を省略可能。
  • 戻値の型と関数本体の間の =を記載しないと戻値の型がUnit型となってしまう。Unit型はjavaで言うvoidに相当。戻り値無しとしたい場合は戻り値の型にUnitを指定します。基本=は省略しない。
  • 引数はvalで定義されるため、再代入はできません。

例:

def greet(arg: String): String = {
  "hello " + arg
}

↓次のようにも書ける

def greet(arg: String) = "hello" +arg

Scalaの変数について

valとvar2つの変数

Scalaには変数を定義するにはvalまたはvarを使います。

scala> val text1 = "foo"
scala> var text2 = "bar"

val はJavaで言うところのfinal修飾子が付いた変数で再代入ができない。 var にはこの制約はありません。

scala> val text3 = "hello"
// val text3 = text3 + "world"
// これはできない。コンパイルエラーとなる。

また下記のようにした場合、mとは別の新しいインスタンスが返される。

scala> val m = Map(1->"japan",2->"usa",3->"chaina")
scala> m + (4 -> "russia")
scala> println(m)の結果はkey が1,2,3のMapが出力されます。

val は再代入はできないが再定義は可能

scala> val color = "red"
scala> println(color) // red
scala> val color = "blue"
scala> println(color) //blue

valを使うことでどのタイミングで参照しても同じ値を返す「参照透過性」がある。 この参照透過性が関数型プログラミングにとっては重要とのこと。また変数の代入やIO処理のプログラムの実行によって状態が変わってしまい。参照処理の結果が変わってしまうことを「副作用がある」と言うらしい。

Scalaを動かす

Scalaの実行について

ScalaにはJavaのようにclassを作り、コンパイルしてから実行する方法の他、シェルスクリプトのように実行することも可能です。

入力してすぐに出力を得るには対話式シェル(REPL)が有効です。

コマンドラインscalaと入力することで対話式シェルを起動できます。

対話式シェルでScalaを実行

$ scala

下記のように表示されます。

scala> 

コンソールに出力する

出力

printlnは改行付きで出力します。

scala> print("hello")
scala> println("hello world")

printやprintlnはPredefという自動的にインポートされるオブジェクトに定義されています。

プログラムっぽいところはまだ無いけどとりあえず動かせた。 次は変数の定義についてを予定

Scalaのセットアップ

Scalaの準備

JDKのインストー

ScalaJVM上で動作するため、実行するにはJDKが必要です。

Java SE - Downloads | Oracle Technology Network | Oracle

Scalaのインストー

Scalaのランタイムは以下からDLしてPATHに追加します。

The Scala Programming Language

Homebrewからでもインストールできます。

brew.sh

$ brew install scala

インストールできたか確認

下記のコマンドでScalaのバージョンが表示されたらOK。

$ scala -version

Scalaの型パラメータについて

Scalaの型パラメータについて調べたことをメモ

型パラメータとは?

Javaで言うジェネリックに該当するもの。 下記のようにすると引数に文字列型以外は指定出来ない。非変という。

val list = List[String]("Hello", "World", "!")

メソッドに型パラメータをつけるには?

メソッド名の後ろに型パラメータをつける。 複数必要な場合はカンマで区切ることができる。

val m = Map(1, "ONE")
def foo[A, B, C](a: A , b: B, c: C) = c + ( a -> b)


foo(2, "TWO", m)
//  scala.collection.immutable.Map[Int,String] = Map(1 -> ONE, 2 -> TWO)
// +メソッドは新しいMapを返している。
// またfoo("3", "THREE", m)も出来ない。"3"がInt型でなく文字列型のため。