在学习Scala的时候比较头疼的问题就是下划线的用法,有点多也有点杂乱,遂想整理一下。以下都是下划线的用法,初学Scala肯定还有没有见到的用法,还请看到的大神能够不吝赐教。
1、_*,告诉编译器把参数当做参数序列处理。这个是用在变长参数传参的时候。当我们想给变长参数传入一个序列,有时是不被允许的,因为函数限制了传入的参数必须是单个参数,这时我们就可以使用_*了
def
main
(
args
: Array[
String
]): Unit = {
println
(
sum
(
1
to
5
: _*))
}
def
sum
(
numb
: Int*) = {
var
res
=
0
for
(
n
<-
numb
){
res
+=
n
}
res
}
2、在元组中,可以使用_1、_2等来访问其组元
val
_tuple
= (
1
,
3.14
,
"McCloy"
)
println
(
_tuple
.
_1
+
","
+
_tuple
.
_2
+
","
+
_tuple
.
_3
)
3、_用来指代集合中的当前元素,用法有点像this。StringOps中的partition方法返回一对字符串,分别包含了满足某个条件和不满足某个条件的字符:
在这个例子中,_就是依次指代构成字符串的每个字符。
4、
def valueAtOneQuarter(f: (Double) => Double) = f(0.25)
当我们将一个匿名函数传递给另一个函数或方法时,Scala会尽可能的帮助我们推断出类型信息。举例来说,我们不需要将代码写成
valueAtOneQuarter((x: Double) => 3 * x) //0.75
由于valueAtOneQuarter方法知道我们会传入一个类型为(Double)=>Double的函数,我们可以简单的写成:
valueAtOneQuarter((x) => 3 * x)
对于只有一个参数的函数,我们可以略去参数外围的():
valueAtOneQuarter(x => 3 * x)
如果参数咋=>右侧只出现了一次,我们可以使用_替换掉它:
valueAtOneQuarter(3 * _)
需要注意的是,以上的这些写法是在参数类型已知的情况下有效。
val fun
= 3 * _ //错误,无法推断类型
val fun = 3 * (_: Double) //OK
val fun: (Double) => Double = 3 * _ //OK,因为已经给出了fun参数类型的定义
当然最后一个定义很造作。不过它展示了函数是如何被作为参数传入的。
5、val fun = ceil _ 将ceil方法转化成函数
6、在模式匹配中,case _的作用类似于java switch case语法中的default。如果在模式匹配中没有 case _ ,在没有模式能匹配的情况下,程序将会抛出MatchError
7、
var
master
: ActorSelection = _
这就类似于新建一个字符串,然后把字符串初始化为null。