Scala控制抽象
private def filesHere = (new java.io.File(".")).listFiles() def filesEnding(query: String) = for(file <- filesHere; if file.getName.endsWith(query)) yield file def filesContaining(query : String) = for(file <- filesHere; if file.getName.contains(query)) yield file def filesRegex(query: String) = for(file <- filesHere;if file.getName.matches(query)) yield file 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(_)) //def filesRegex(query: String) = filesMatching(query, _.matches(_))
用在filesEnding方法里的函数文本_.endsWith(_) 等同于(fileName: String, query: String) => fileName.endsWith(query)
原因是filesMatching带一个函数,这个函数需要两个String参数,不过你不需要指定参数类型。因此,你也可以写成(fileName, query) => fileName.endsWith(query)。由于第一个参数,fileName,在方法体中被第一个使用,第二个参数,query,第二个使用,你也可以使用占位符语法:_.endsWith(_)。第一个下划线是第一个参数,文件名的占位符,第二个下划线是第二个参数,查询字串的占位符。
以下是使用了这种方式的方法去判断是否传入的List包含了负数的例子:
def containsNeg(nums: List[Int]): Boolean = { var exists = false for (num <- nums) if (num < 0) exists = true exists } scala> containsNeg(List(1, 2, 3, 4)) res0: Boolean = false scala> containsNeg(List(1, 2, 3, -4)) res1: Boolean = true
不过更简洁的定义这个方法的方式是通过在传入的List上调用高阶函数exists
def containsNeg(nums: List[Int] = nums.exists(_<0)
Curry化
展示了curry化后的同一个函数。代之以一个列表的两个Int参数,你把这个函数应用于两个列表的各一个参数
在第一个函数上应用1——换句话说,调用第一个函数并传入1——会产生第二个函数,在第二个函数上应用2产生结果
first和second函数只是curry化过程的一个演示。他们并不直接连接在curriedSum函数上。尽管如此,仍然有一个方式获得实际指向curriedSum的“第二个”函数的参考。你可以用偏应用函数表达式方式,把占位符标注用在curriedSum里.
编写新的控制结构:
op的类型是Double => Double,就是说它是带一个Double做参数并返回另一个Double的函数。