9

シンボルを利用するscalaのコードスニペットをたくさん読んだことがありますが、=>実際にそれを理解することはできませんでした。インターネットで検索しようとしましたが、包括的なものは見つかりませんでした。シンボルがどのように使用されるか/使用できるかについてのポインタ/説明は本当に役に立ちます。

(より具体的には、演算子が関数リテラルでどのように表現されるかについても知りたいです)

4

1 に答える 1

19

値/名前を渡すだけでなく=>、関数を定義するために使用される代替構文である関数リテラルを定義するために使用されます。

例の時間。別の関数を受け取る関数があるとします。コレクションはそれらでいっぱいですが、 を選択しfilterます。filterをコレクション (List など) で使用すると、指定した関数が false を返す原因となる要素が取り除かれます。

val people = List("Bill Nye", "Mister Rogers", "Mohandas Karamchand Gandhi", "Jesus", "Superman", "The newspaper guy")
// Let's only grab people who have short names (less than 10 characters)
val shortNamedPeople = people.filter(<a function>)

他の場所 ( 、おそらく) から実際の関数を渡すこともできdef isShortName(name: String): Booleanますが、そこに直接配置する方が適切です。残念ながら、関数リテラルを使えばできます。

val shortNamedPeople = people.filter( name => name.length < 10 )

ここで行ったことは、文字列 (peopleは 型であるためList[String]) を受け取り、ブール値を返す関数を作成することです。かなりクールですよね?

この構文は、多くのコンテキストで使用されます。別の関数を受け取る関数を書きたいとしましょう。この他の関数は文字列を受け取り、Int を返す必要があります。

def myFunction(f: String => Int): Int = {
  val myString = "Hello!"
  f(myString)
}
// And let's use it. First way:
def anotherFunction(a: String): Int = {
  a.length
}
myFunction(anotherFunction)
// Second way:
myFunction((a: String) => a.length)

それが関数リテラルです。と に戻るby-nameby-value、必要になるまでパラメーターを強制的に評価しないようにするトリックがあります。典型的な例:

def logger(message: String) = {
  if(loggingActivated) println(message)
}

これは問題ないように見えますが、実際には が呼び出さmessageれたときに評価されます。評価に時間がかかるlogger場合は?messageたとえばlogger(veryLongProcess())、 whereveryLongProcess()は文字列を返します。おっと?あまり。関数リテラルに関する知識を使用して、veryLongProcess()実際に必要になるまで呼び出されないようにすることができます。

def logger(message: => String) = {
  if(loggingActivated) println(message)
}
logger(veryLongProcess()) // Fixed!

loggerパラメータをとらない関数を取り込んでいます (したがって、=>左側のネイキッド)。以前と同じように使用できますが、message( で) 使用されたときにのみ評価されるようになりましたprintln

于 2012-09-21T12:08:22.770 に答える