Step by Step Scala [vol.02]

第二回も参加しました。
以下、ダラダラと日記ですらないメモ書き。


メソッド(関数)定義で = (イコール)を入れないとUnit型戻り値になる。
つまり、何も返ってこない。
この仕様って、誰が得するんや...

def test{ 100 }
test: ()Unit
def test2() = { 100 }
test2: ()Int


Q:()と{}はどう違いますか?
A:丸括弧は1個の引数しか渡せないが中括弧の場合は文をセミコロンで区切って複数書けて
最後に評価された文が関数に渡される。との事。


matchの後の{}もそうなのかな??
関数定義のdefの後の{}もそうなのかな??


javapコマンドでクラスファイルのVMコードがJavaに逆アセンブルされて覗けるとのこと。ふむふむ。
本に載ってない事を教えてくれるのが勉強会の良い所。
Scalaのmethodとfieldはどちらもfieldとして定義されている事を確認しました。


Scalaでイコールで終わるメソッド名を定義するのは
アンダースコアをかまして定義する。と。

class Employee {
  private var n:String = ""
  def name = n
  def name_=(na:String) = n = na
}
val e = new Employee
e.name = "Name"


この辺はRubyの方がアンダースコアが不要な分、素直に書けるよなぁ。

class Employee
  @n = ""
  def name
    @n
  end
  def name=(na)
    @n = na
  end
end
e = Employee.new
e.name = "Name"


love+ という名前のメソッドの場合もscalaではアンダースコアが必要らしい。
記号で終わる場合かな。


噂の名前渡しパラメータについて
メソッドの引数の型で名前渡しである事を宣言すると
メソッド呼び出し時、引数の所に書いた式は評価されず、
メソッド内で最初に参照された時に評価される仕組み。


具体的には(つまんない例ですけど)
引数の型の所に => を書いておく。

def test(b: => Boolean) = {
  if(b)
    true
  else
    false
}


で、使う時は以下のように使う。

test( 1 > 2 )

上記のように書いてあると、通常 ( 1 > 2 )が評価されて
その評価結果がtestに渡されそうですけど、
名前渡しパラメータの場合は 1 > 2 がそのまま引数に渡される。
で、testメソッドの中でbが必要になった時に一回だけ評価される仕組み。
遅延評価できる訳ですね。
testメソッドの中で複雑に分岐していて、bの値を一度も使わない場合などは
1 > 2 を評価しなくても良い訳で無駄になるので、そういう場合に使えるようです。
関数作って渡しても同じ事ができますけど、そのコード量と見た目をケチる事ができます。


で、言いたい事はわかったのですが、
ライブラリなど、どのメソッドが名前渡しパラメータなのか
きちんと把握しておかないと、思わぬ所で評価が遅延されそうな気もしますね。


Step by Step Scala [vol.02]@scala-be : ATND


Scalaスケーラブルプログラミング[コンセプト&コーディング] (Programming in Scala)
Martin Odersky Lex Spoon、Bill Venners
インプレスジャパン
売り上げランキング: 3863