2011-12-29 7 views
3

Я изучаю Scala с Scala-IDE в Eclipse. Следуя главе 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 

и все три вызова к printArray() в методе test() теперь говорить об этом:

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

Что все это значит? Scala не должен вести себя как Python, когда выравнивание кода может испортить поток кода ... так как получается, что удаление пустой строки между первой и второй строками тела метода filterFiles() вызывает такую ​​серьезную ошибку? Является ли это ошибкой где-то или это происходит непосредственно из правил Scala? Примечание: если я добавлю ; между строкой, она сортирует все. Это просто ошибка с точкой с запятой?

+0

Это не похоже на Python, поскольку вы не должны полагаться на выравнивание или пробелы: вы можете добавить точки с запятой в конце каждого оператора, например. – Philippe

+0

Да, это определенно вещь, которую нужно помнить. – noncom

ответ

4

Когда метод объекта не может ни один, или один аргумент можно назвать как

val files = object method arg 

или, в вашем фрагменте кода

val files = object method 
    arg 

В коде компилятор хочет вызвать listfiles с выражением for в качестве агита, который возвращает Array[File]. И жалуется, что listFiles не реализует этот аргумент. Пустая строка предотвращает обработку выражения for в качестве параметра для функции listFiles

+0

Хмм, я не заметил ни на одном другом соответствующем языке, что пустая строка могла бы сделать такой трюк. Несколько загадочный опыт) – noncom

+1

В Scala IDE есть функция, называемая [show inferred semicolons] (http://scala-ide.org/docs/user/features/typingviewing.html#show-inferred-semicolons), которая добавляет выведенные точки с запятой в текущем редакторе. Это помогает устранить подобные ошибки. –

2

Похоже, что проблема вывода с точкой с запятой, как вы предлагаете, я думаю, что компилятор ожидает аргументы метода, если вы оставите круглые скобки. Вместо того, чтобы точка с запятой, вы можете добавить круглые скобки после listFiles:

val files = (new java.io.File(path)) listFiles() 
Смежные вопросы