2016-01-08 51 views
0

我想學會用Scala編程,和我遇到有關underscore.Here一些問題是代碼:I(初學者)的感覺強調是混亂

FileMatcher.filesContaining("hello").foreach(println(_)) 

FileMatcher.filesContaining("hello").foreach(println((_:java.io.File).getName)) 

我的問題是,如果下劃線代表函數的形式參數(對嗎?,我已經看到了關於下劃線的一些答案),爲什麼第一個代碼運行良好,但第二個崩潰?

============================================== =======================

整個代碼(對不起,我英文不好。 「嘩啦啦」 的意思編譯失敗)

object FileMatcher{ 

    private def filesHere = (new java.io.File(".")).listFiles 

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

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

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

} 

FileMatcher.filesContaining("hello").foreach(println(_)) 

FileMatcher.filesContaining("hello").foreach(println((_:java.io.File).getName)) 
+1

你的意思是'墜毀'?你能解釋更多的錯誤嗎?問題標題也應該改變,以更清楚地反映問題。 – Jus12

+0

@Kermit嘗試使用適當的語法並在逗號後面使用空格,以便用戶不會跳過您的問題。 – Glubus

+0

什麼是'FileMatcher'?請包含所有信息以重現問題。 –

回答

5
val seq: Seq[java.io.File] = Seq(new java.io.File("hello")) 

在這裏:

seq.foreach(println(_)) 

...下劃線代替的println與個參數e匿名函數的參數(傳遞給foreach的函數)。這等於

seq.foreach(f => println(f)) 

事實上,你甚至可以縮短這:

seq.foreach(println) 

而在:

seq.foreach(println(_.getName)) 

...你會x => x.getName傳遞函數println。這不會編譯,因爲現在你忽略了foreach花費1元數的函數,例如,你可以嘗試寫:

seq.foreach(f => println(_.getName)) 

然後仍然Scala有不知道的x => x.getName參數類型是什麼(因爲有沒有任何可以推斷的背景)。所以:

seq.foreach(f => println((x: java.io.File) => x.getName)) 

輸出:

<function1> 

哎呀。這不是你想要的。您正在打印函數的字符串表示形式(不應用該函數)。很明顯,你也沒有做任何事情f。所以你看,內在的功能太多了。

正確的是:

seq.foreach(f => println(f.getName)) 

斯卡拉不允許您可以縮短這seq.foreach(println(_.getName)),因爲有東西在中間foreachgetName之間,那就是println方法。