Groovy — закрытие — чтение CSV

Есть ли кто-нибудь, кто может объяснить мне, как работает этот фрагмент кода?

class CSVParser {  
    static def parseCSV(file,closure) {  
        def lineCount = 0  
        file.eachLine() { line ->  
            def field = line.tokenize(",")  
            lineCount++  
            closure(lineCount,field)  
        }  
    }  
}  

use(CSVParser.class) {  
    File file = new File("test.csv")  
    file.parseCSV { index,field ->  
        println "row: ${index} | ${field[0]} ${field[1]} ${field[2]}"  
    }  
}  

Ссылка: http://groovy-almanac.org/csv-parser-with-groovy-categories/

«parseCSV» выглядит как метод, но используется в «файле» как закрытие. Закрытие является одним из параметров "parseCSV" и наиболее запутанным - внутри этого метода есть только closure(lineCount,field) без какой-либо внутренней функциональности.

Как именно это работает с замыканием на file.parseCSV и use(CSVParser.class)?


person Daniel    schedule 27.05.2013    source источник


Ответы (1)


Это Category; проще говоря, они делают метод класса "становящимся" методом объекта первого аргумента. Замыкание, переданное в качестве параметра, не дополняет пример; это может быть строка или что-то еще:

class Category {
  // the method "up()" will be added to the String class
  static String up(String str) {
    str.toUpperCase()
  }

  // the method "mult(Integer)" will be added to the String class
  static String mult(String str, Integer times) {
    str * times
  }

  // the method "conditionalUpper(Closure)" will be added to the String class
  static String conditionalUpper(String str, Closure condition) {
    String ret = ""
    for (int i = 0; i < str.size(); i++) {
      char c = str[i]
      ret += condition(i) ? c.toUpperCase() : c
    }
    ret
  }
}

use (Category) {
  assert "aaa".up() == "AAA"
  assert "aaa".mult(4) == "aaaaaaaaaaaa"
  assert "aaaaaa".conditionalUpper({ Integer i -> i % 2 != 0}) == "aAaAaA"
}

Также именно так работает расширения Groovy.

person Will    schedule 27.05.2013