2011-12-29 30 views
3

我在Eclipse中學習Scala和Scala-IDE。雖然遵循了第9章:控制抽象,第1部分:減少Scala編程中的代碼重複,但我已經從書中編寫了代碼(完全如下),它工作的很好!當我開始刪除不必要的空白行時,發生了一件奇怪的事情。這裏是去除空行前的全部代碼在filterFiles()方法:Scala-IDE或Scala不合理的語法歧義

object Code_c09s01_ControlAbstraction extends App{ 

    object FilesFilter { 

    private def filterFiles(path: String, pattern: String, matcher: (String, String) => Boolean) = { 

     val files = (new java.io.File(path)) listFiles 

     for(file <- files if matcher(file.getName, pattern)) yield file 
    } 

    def filterExtension(path: String, pattern: String) = filterFiles(path, pattern, _.endsWith(_)) 
    def filterName(path: String, pattern: String) = filterFiles(path, pattern, _.contains(_)) 
    def filterRegex(path: String, pattern: String) = filterFiles(path, pattern, _.matches(_)) 
    } 

    def printArray[A](message: String, arr: Array[A]) { 
    println (message) 
    println (arr mkString("\n")) 
    } 

    def test() { 
    val path = "C:\\"; 

    printArray("--- filtering by ext: ---", FilesFilter.filterExtension(path, ".txt")) 
    printArray("--- filtering by containment: ---", FilesFilter.filterName(path, "1")) 
    printArray("--- filtering by regex: ---", FilesFilter.filterRegex(path, ".")) 
    } 

    test 

} 

這工作就好了!然而,從filterFiles()方法去除空白行後,該方法現在看起來是這樣的:

private def filterFiles(path: String, pattern: String, matcher: (String, String) => Boolean) = { 
    val files = (new java.io.File(path)) listFiles 
    for(file <- files if matcher(file.getName, pattern)) yield file 
} 

而且IDE給我的錯誤在身上的兩條線。第一行的錯誤說:

ambiguous reference to overloaded definition, both method listFiles in class File of type (x$1: java.io.FileFilter)Array[java.io.File] and method listFiles in class File of type 
(x$1: java.io.FilenameFilter)Array[java.io.File] match argument types (Null) 

在第二行的錯誤說:

illegal start of simple expression 

和所有在test()方法的三個電話到printArray()現在還講這個:

type mismatch; found : Unit required: Array[?] 

這是什麼意思?當代碼對齊可能會破壞代碼流時,Scala不應該像Python一樣行事......那麼如何去除filterFiles()方法正文的第一行和第二行之間的空白行會產生如此嚴重的錯誤?它是一個錯誤的地方,還是直接遵循Scala的規則?注意:如果我在該行之間添加;,它會將所有內容排序。它只是分號推理錯誤?

+0

它與Python不同,因爲您不需要依賴對齊或空格:例如,可以在每個語句的末尾添加分號。 – Philippe 2011-12-29 15:47:08

+0

是的,這絕對是一件值得記住的事情。 – noncom 2011-12-29 17:28:26

回答

4

當對象的方法可以沒有或一個參數,你可以這樣調用它

val files = object method arg 

,或者在你的代碼片段

val files = object method 
    arg 

在您的代碼中,編譯器想要將listfilesfor表達式作爲返回Array[File]的文件夾。並抱怨listFiles沒有實現這種類型的參數。空行防止將for表達式作爲參數處理listFiles函數

+0

嗯,我沒有注意到任何其他相關的語言,空行可以做這種伎倆。有點令人費解的體驗)​​ – noncom 2011-12-29 17:29:50

+1

Scala IDE有一個名爲[顯示推斷分號](http://scala-ide.org/docs/user/features/typingviewing.html#show-inferred-semicolons)的功能,它添加了推斷分號在當前編輯器中。這有助於排查像這樣的錯誤。 – 2011-12-30 12:48:55

2

看起來像分號推理問題,如你所建議的,我猜如果你將圓括號取出,編譯器會期望方法參數。相反分號,你可以listFiles後加括號:

val files = (new java.io.File(path)) listFiles()