看用Scalding写的MapReduce程序时,看到有这么个函数定义:
def flatMap[A, T](fs: (Fields, Fields))(fn: A => TraversableOnce[T])(implicit conv: TupleConverter[A], setter: TupleSetter[T]): Pipe = {
conv.assertArityMatches(fs._1)
setter.assertArityMatches(fs._2)
each(fs)(new FlatMapFunction[A, T](fn, _, conv, setter))
}调用的时候是这样:
flatMap('line -> 'word){ lineA : String => tokenize(lineA) } //tokenize(是一个函数, 不用考虑)
我就不明白了:
函数定义的明明是3层括号,也就像是3层柯里化似的, 但是调用函数的时候, 为什么用一个()和一个{}就搞定了呢??
而且lineA : String => tokenize(lineA)这句是什么意思?! 如果是传入一个匿名函数作为参数,也应该是加小括号啊: (lineA : String) => tokenize(lineA)
def flatMap[A, T](fs: (Fields, Fields))(fn: A => TraversableOnce[T])(implicit conv: TupleConverter[A], setter: TupleSetter[T]): Pipe = {
conv.assertArityMatches(fs._1)
setter.assertArityMatches(fs._2)
each(fs)(new FlatMapFunction[A, T](fn, _, conv, setter))
}调用的时候是这样:
flatMap('line -> 'word){ lineA : String => tokenize(lineA) } //tokenize(是一个函数, 不用考虑)
我就不明白了:
函数定义的明明是3层括号,也就像是3层柯里化似的, 但是调用函数的时候, 为什么用一个()和一个{}就搞定了呢??
而且lineA : String => tokenize(lineA)这句是什么意思?! 如果是传入一个匿名函数作为参数,也应该是加小括号啊: (lineA : String) => tokenize(lineA)
第二个参数是function,调用时{}用来代替具体的函数
第三个参数是implicit,上下文中有implicit的引用就可以省略这个参数
lineA : String => tokenize(lineA)意思是String类型的变量lineA,把他传入函数tokenize
人家这个语言就是这种写法,为啥一定要是命令式语言的写法 (lineA : String) => tokenize(lineA)
lineA : String => tokenize(lineA) 传给了 (fn: A => TraversableOnce[T])
implicit conv: TupleConverter[A], setter: TupleSetter[T] 这个不用传,只要上下文中有implicit定义就行
在scala中如果调用函数只有一个参数,调用时可以使用{}来替代()
这里用了柯里化,(fn: A => TraversableOnce[T]) 小括号中只有一个参数,所以在调用时 可以使用{} 代替()
比如下面的例子
object Test {
def f(a:Int) = {a}
def main(args: Array[String]) {
val a = f{15} // 这里用{}代替()
println(a)
}
}