6

私はScalaを学び始めており、Programming inScalaの教科書の抜粋に出くわしましたが、よくわかりません。誰かが私を助けることができることを望んでいましたか?

これは、Scala、2ndEditionでのプログラミングのリスト9.1からのものです。

object FileMatcher {
    private def filesHere = (new java.io.File(".")).listFiles
}

private def filesMatching(matcher: String => Boolean) = 
    for (file <- filesHere; if matcher(file.getName)) yield file

def filesEnding(query: String) = 
    filesMatching(_.endsWith(query)) // ???

def filesContaining(query: String) = 
    filesMatching(_.contains(query)) // ???

def filesRegex(query: String) = 
    filesMatching(_.matches(query)) // ???

が付いている行と少し混乱しています// ???。どういうわけかを使用すると、に_渡される匿名関数が作成されfilesMatchingますか?または、_これとは何の関係もありません。代わりに、コンパイラはそれfilesMatchingが関数を必要としていることを認識し、したがって式として実行_.endsWith(query)されず、代わりに式を関数にしますか?

4

3 に答える 3

14

extended definition

Anonymous function are defined, in their more verbose and complete form, as

(a: A, b: B, ...) => function body //using a, b, ...

E.g.

(a: String, b: String) => a ++ b // concatenates 2 Strings

inferred types

if the context provides the needed information (as when a higher order function expects a specific signature for its function arguments), you can omit the parameters' types, as

(a, b, ...) => function body //using a, b, ...

E.g.

val l = List(1, 2, 3)

//you can omit the type because filter on List[Int] expects a (Int => Boolean)
l.filter(i => i < 3)

placeholder syntax

Finally you can use a shorter form still, if your parameters are used once each and in the same order that you declare them, by the function body, as

_ ++ _ // which is equivalent to (a, b) => a ++ b

Each _ is a placeholder for the function's arguments

E.g.

filesMatching's argument is a function of type String => Boolean so you can use

_.endsWith(query) // equivalent to (s: String) => s.endsWith(query)
_.contains(query) // equivalent to (s: String) => s.contains(query)
_.matches(query)  // equivalent to (s: String) => s.matches(query)
于 2013-01-24T15:29:22.903 に答える
3

ここ_で使用されている は、関数の引数の省略形です。したがってfilesMatching(_.endsWith(query))、 と同等filesMatching(f => f.endsWith(query))です。の関数を引数としてfilesMatching持つように、コンパイラは が hereであると予想されるとString => Boolean推測できます。したがって、この式が無名関数であることは正しいです。fString

于 2013-01-24T15:10:37.053 に答える