読者です 読者をやめる 読者になる 読者になる
無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

引数を受け付ける関数の定義/「値渡し」と「参照渡し」

ScalaByExample - Example4.2 Parametersを読みました。

引数を受け付ける関数の定義

「def <関数名>(<仮引数:引数型..>) : <戻り値の型> = ...」として、引数を持つ関数を定義できます。

// 「def <名前>(<引数>):<戻り値型> => ...」で引数を受け取る関数を定義できる。 
def foo(i:int):int = 3*i
println( foo(3) ) // 9

// ↓ちなみにさすがにこんなことはできない
// val b(i:int);int = 3*i

まぁ、普通ですね。

引数の「値渡し」と「参照渡し」

引数には、「値渡し」「名前渡し」があります。

  • 値渡し
    • 関数の実行前に引数が評価され、その値が関数に渡される渡し方。Javaなんかはこれしかない。
    • ○引数の評価が1回だけ行なわれるため、関数内で引数を複数回使っても無駄な処理が少ない。
  • 名前渡し
    • 関数の実行途中で、引数の値が必要になった場合に評価が行なわれる渡し方。
    • ○引数が不要な場合評価が行なわれないため、無駄な処理を減らせる場合がある。

Scalaでは、両方が使えます。

  • 関数の定義時に、普通に引数を定義すると「値渡し」される引数となります。
  • 仮引数の後に「=>」をつけて定義すると「名前渡し」される引数となります。
// 数値を返す関数a
def a = { 
  println( "a" )
  3 
}

// 数値を2倍にする関数
// 引数は「値渡し」で渡される。
def x2( a:int ):int = { 
  println("x2")
  a+a
}

// 実行
println( x2( a ) )
// このとき、関数は以下の順で実行される。
//   1.. a
//   2.. x2

println("--")

// 引数の後に「=>」をつけると、「名前渡し」となる。
def x2_delay( a: => int ):int = { 
  println("delay x2")
  a+a
}

// 実行
println( x2_delay( a ) )
// このとき、関数は以下の順で実行される。
//   1.. x2_delay
//   2.. a
//   3.. a (aは2回評価される)

実行結果です。

a
x2
6
--
delay x2
a
a
6

JavaScriptだと関数を引数で渡して必要に応じて評価するみたいな感じでやるなー。Rubyもブロックを渡すことで似たようなことができます。両方とも特殊なオブジェクトを渡すことで評価のタイミングを変更できるようにしているけど、Scalaだとそんなことしなくても、関数定義時に指定しておくだけで引数の評価のタイミングを制御できる、というわけですかね。ふむふむ。