高卒文系Scala vol.4 -関数定義 -

今回は、以下Scala本の2.3辺り。Scalaの関数定義について。

Javaを勉強していると、「関数」って言葉を全く聞かず、「メソッド」という言葉を頻繁に聞きます。

この「関数」と「メソッド」って、どう違うんでしょうか?

ここら辺は物凄くナイーブ(?)な話なので、チキンな僕は明言するのは避けますが、

だいたいこんな感じかなーと思います。

メソッド(method)

オブジェクトに対する操作を表すサブルーチン。

処理の結果を返す・返さないは、個々のメソッドの定義による。

呼び出し時のオブジェクトの状態によって結果が変わる事があり、オブジェクトの状態に副作用を及ぼす事もある。

関数(function)

処理結果を戻り値として呼び出し元に返すサブルーチン。

(戻り値を返さない関数も定義できるけど、厳密には関数とは呼ばないみたい)

とりあえず、クラスとかオブジェクトとか関係なくても定義できるのが関数、って事で・・・

(C++のメンバ関数とか、名前的にどっちなのか怪しいのはありますけど)

結果値を返す関数

Javaでのサブルーチンの定義は、必ずクラスのメンバである必要がありますが、 Scalaでは必ずしもクラスのメンバである必要はありません。

【訂正】

Javaでのサブルーチンの定義が必ずクラスメンバである必要があるのと同様に、

Scalaでのサブルーチンもクラスメンバである必要があるそうです。

バカ丁寧に記述した関数定義の一例。

def getSum(x: Int, y: Int) : Int = {
  return x + y
}

説明。

  • 「getSum」: 関数名。その後の()内が、引数リスト。引数の型は省略不可。
  • 「: Int」: 関数の結果型。省略可だけど、可読性の為に明示的に記述する事が推奨されている模様。
  • 「=」 : 代入の「=」。今はスルー。こう書けば関数定義できるよ、という事で。

そして、 {} 内に処理を記述します。

この例のように関数の処理が一つの式で済む場合、 {} の代わりに () で定義する事もできますし、 {} 自体を省略する事もできます。

この例の場合、結果値を返すのに「return」は付けても付けなくてもOKです。

Scalaでは、関数ブロックの一番最後に記述された式の結果を関数の結果値として呼び出し元に返します。

以下のコードは全て、上記のコードと全く同じ意味になります。

// 「return」無し
def getSum(x: Int, y: Int) : Int = {
  x + y
}

// 「return」無し + {} を () に
def getSum(x: Int, y: Int) : Int = (
  x + y
)

// 「return」無し + {} 省略
def getSum(x: Int, y: Int) : Int = x + y

// 「return」無し + {} 省略 + 結果型指定省略
def getSum(x: Int, y: Int) = x + y

意味のある結果値を返さない関数

関数型言語であるScalaでは、「結果値を返さない」関数は定義できません。

その代わりに、Scalaでは「意味のある結果値を返さない」関数を定義します。

バカ丁寧に記述した「意味のある結果値を返さない」関数の一例。

def message() : Unit = {
  println("Don't Mind!")
}

結果型として定義されている「Unit」は、「java.lang.Void」クラスのインスタンスのようなものです。

ちなみにJavaの「void」はScalaだとUnitにマッピングされます。

「Unit」は、主に副作用を及ぼす「メソッド」の結果型に定義される事が多いようです。

ちなみに、上記コードの関数を標準出力関数である「println」に引数として渡してやると・・・

scala> def message() = println("Don't Mind!")
message: ()Unit
scala> println(message())
Don't Mind!
()

「Unit」型のオブジェクトの文字列表現は「()」のようです。うん、意味がない!

まぁ「Unit」はJavaの「void」と同等と考えても良さそうです。

言語設計者のMartin Odersky氏が「純粋関数型言語と謳ってるからには関数は必ず何かしらの値を返さなきゃダメだよね」

と言ったかどうかは知りませんが・・・

「Unit」は、Scalaをオブジェクト指向+純粋関数型としてより忠実に設計した結果の一つ、なのかもしれません。

このエントリーをはてなブックマークに追加
comments powered by Disqus