シンボルを利用するscalaのコードスニペットをたくさん読んだことがありますが、=>
実際にそれを理解することはできませんでした。インターネットで検索しようとしましたが、包括的なものは見つかりませんでした。シンボルがどのように使用されるか/使用できるかについてのポインタ/説明は本当に役に立ちます。
(より具体的には、演算子が関数リテラルでどのように表現されるかについても知りたいです)
シンボルを利用するscalaのコードスニペットをたくさん読んだことがありますが、=>
実際にそれを理解することはできませんでした。インターネットで検索しようとしましたが、包括的なものは見つかりませんでした。シンボルがどのように使用されるか/使用できるかについてのポインタ/説明は本当に役に立ちます。
(より具体的には、演算子が関数リテラルでどのように表現されるかについても知りたいです)
値/名前を渡すだけでなく=>
、関数を定義するために使用される代替構文である関数リテラルを定義するために使用されます。
例の時間。別の関数を受け取る関数があるとします。コレクションはそれらでいっぱいですが、 を選択し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-name
とby-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
。