下面的问题,表面上看是小括号与花括号的问题。
// map方法这样写不能编译通过
scala> List(2).map( case 2 => "OK" )
// 换做花括号就可以了
scala> List(2).map{ case 2 => "OK" }
不了解原因的话,觉得很诡异。分析一下,首先,map方法接受一个函数,这个函数将List中的元素映射为其他类型。
实际上case 2 => "OK"
不是一段lambda表达式(也就是说它不是函数),它是一段模式匹配语句。
那为什么在第二行可以编译通过呢?
稍微有点基础的话,会清楚方法的花括号有2种意思:
1)scala中函数的小括号,可以用花括号来表示,即foo{xx}
与 foo(xx)
是一回事儿。
2)对于只有一个参数的方法,其小括号是可以省略的,map(lambda)
可写为 map lambda
,即这块{case 2 => "OK"}
连同花括号整体是一个lambda(函数字面量)。
这儿显然是第2个(追究原因就要看编译器在语法解析式的优先级了,看样子把花括号对待为lambda字面量的一部分要高于把花括号当作小括号来对待),那么为什么加了花括号的{case 2 => "OK" }
就可以当作一段函数字面量?
这要引出偏函数的概念,所谓偏函数(也叫部分函数)与完全函数想对应,普通的方法都是完全函数,即 f(i:Int) = xxx
是将所有Int类型作为参数的,是对整个Int集的映射;而偏函数则是对部分数据的映射,比如上面{case 2=> "OK" }
就仅仅只对2做了映射。偏函数的实现都是通过模式匹配来表达的。
scala> val p:PartialFunction[Int,String] = { case 2 => "OK" }
因为偏函数是通过 { case x => y }
这种特殊的方式来描述的,上面的{case 2=>"OK"}
就被当作了一段偏函数字面量,而偏函数背后的类型PartialFunction[A,B]
是继承自Function1[A,B]
的,所以将这段匿名的偏函数传给map方法是ok的。
小结:表达式 {case x=>y}
会被当作偏函数字面量。
精彩!
scala里面大小括号并不是一回事儿,虽然说很多时候可以替换。大括号之所以在小括号的地方能使用,是因为该小括号仅需一个参数,故小括号可以省略,而大括号的内容最后会被evaluate成一个结果,并作为小括号的参数给予传递。两个参数的小括号就无法直接用大括号替代。
二者还是通常意义上的定位和用法,只不过scala有一套省略策略。具体参考http://stackoverflow.com/a/24985146/2073130
感觉好难懂
可以理解为:
全函数和偏函数的原因吗??
println(Array(7,8,9) map(x=>x+1) mkString “,”)
println(Array(7,8,9) map add1 mkString “,”)
println(Array(7,8,9) map x=>x+1 mkString “,”)
为什么最后一个的map的匿名函数不能省略括号?
println(Array(11,12,13) map(_+1) mkString(“,”))
println(Array(11,12,13) map(_=>_+1) mkString(“,”))
为什么下边的_=>_+1不能被当做一个匿名函数?
好棒 又解决我一个困惑
Pingback: Scala中()与{} - 站壳网