這是一開始最可能寫出來的代碼,代碼很簡單,就是文件名的過濾功能。函數
object FileMatcher { private def files = new File(".").listFiles() def filesEnding(query: String): Array[File] = { for (file <- files; if file.getName.endsWith(query)) yield file } def FilesContaining(query: String): Array[File] = { for (file <- files; if file.getName.contains(query)) yield file } def FilesRegexing(query:String): Unit ={ for (file <- files; if file.getName.matches(query)) yield file } }
定義個filesMatching方法,將邏輯抽象,如今看着就舒服多了。code
但還不夠完美。資源
object FileMatcher { private def files = new File(".").listFiles() def filesEnding(query: String): Array[File] = { filesMatching(query,_.endsWith(_)) } def FilesContaining(query: String): Array[File] = { filesMatching(query,_.contains(_)) } def FilesRegexing(query: String): Unit = { filesMatching(query,_.matches(_)) } def filesMatching(query: String, matcher: (String, String) => Boolean): Array[File] = { for (file <- files; if matcher(file.getName, query)) yield file } }
在邏輯方法中,去掉參數,這樣就更清爽了。get
object FileMatcher { private def files = new File(".").listFiles() def filesEnding(query: String): Array[File] = { filesMatching(_.endsWith(query)) } def FilesContaining(query: String): Array[File] = { filesMatching(_.contains(query)) } def FilesRegexing(query: String): Unit = { filesMatching(_.matches(query)) } def filesMatching(matcher: String => Boolean): Array[File] = { for (file <- files; if matcher(file.getName)) yield file } }
假設你須要打開一個文件,你最後老是須要考慮關閉資源。有沒有什麼辦法,讓咱們不會忽略這個動做。(不使用try())it
object printWriterTest { def withPrintWriter(file: File)(op: PrintWriter => Unit): Unit = { val writer = new PrintWriter(file) try { op(writer) } finally { writer.close() } } }
接下來你能夠這麼使用這個函數io
withPrintWriter(new File("test.txt"))(writer => writer.println("test"))
傳名參數比起簡單的參數傳輸,不同的地方在於。test
簡單的參數傳輸會先計算這個表達式,而傳名參數則在須要它的時候纔會去計算。object
如下示例代碼,只有boolAssert(5/0==0)
纔會拋出錯誤。file
object ByNameAssertTest { def main(args: Array[String]): Unit = { byNameAssert(5 / 0 == 0) boolAssert(5 / 0 == 0) } var assertEnable = false def byNameAssert(predict: => Boolean): Unit = { if (assertEnable && !predict) { throw new AssertionError() } } def boolAssert(predict: Boolean): Unit = { if (assertEnable && !predict) { throw new AssertionError() } } }