scala 下划线用法总结
# Scala 下划线用法总结
# 1. 用于变量的初始化
在 Scala 中,变量在声明时必须显示指定,可以使用下划线对变量进行初始化(使用默认的初始值)。而且该语法只适用于成员变量,不适用于局部变量。例:
class Foo{
//String类型的默认值为null
var s: String = _
}
1
2
3
4
2
3
4
对于 Int 来说,它是 0。
对于 Double 来说,它是 0.0 对于引用类型,它是 null
# 2. 用于导包引入
导包引入时使用_导入该包下所有内容,类比 Java 中的 *。例如:
//Java
import java.util.*;
//Scala
import java.util._
1
2
3
4
5
2
3
4
5
# 3. 用于将方法转变为函数
在 Scala 中方法不是值,而函数是。所以一个方法不能赋值给一个 val 变量,而函数可以。方法可以转换为函数赋值给变量,
Scala中方法和函数是两个不同的概念,方法无法作为参数进行传递,也无法赋值给变量,但是函数是可以的。在Scala中,利用下划线可以将方法转换成函数:
例:
def sum(a:Int,b:Int): Int ={
a + b
}
def main(args: Array[String]): Unit = {
val s = sum _
println(s)
println(s(2,4))
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 4. 用于模式匹配
模式匹配中可以用下划线来作为 Java 中 default 的类比使用,也可以在匹配集合类型时,用于代表集合中元素,例:
println("匹配常量===")
val str = "a"
str match {
case "a" => println("match a")
case _ => println("match default")
}
println("匹配类型===")
val x:Any = 12
x match {
case s:String => println("match String")
case i:Int => println("match Int")
case _ => println("match default")
}
println("匹配以0开头,长度为3的列表===")
val list = List(0,2,3)
list match {
case List(0,_,_) => println("found list")
case _ =>
}
println("匹配以0开头,任意长度的列表===")
list match {
case List(0,_*) => println("found list")
case _ =>
}
println("变量声明中的模式匹配===")
val arr = Array(1,2,3,4,5)
val Array(first, second, _*) = arr //分别将arr中的第一个和第二个值赋给first和second
println(s"first:$first,second:$second")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 5. 用户访问 tuple 元素
val t = (1,2,3)
println(t._1)
1
2
2
# 6. 下划线与星号
向函数或方法传入可变参数 时不能直接传入 Range 或集合或数组对象,需要使用:_*
转换才可传入
# 6.1 变长参数
例如定义一个变长参数的方法 sum,然后计算 1-5 的和,可以写为
scala> def sum(args: Int*) = {
| var result = 0
| for (arg <- args) result += arg
| result
| }
sum: (args: Int*)Int
scala> val s = sum(1,2,3,4,5)
s: Int = 15
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
但是如果写成这种方式就会报错
scala> val s = sum(1 to 5)
<console>:12: error: type mismatch;
found : scala.collection.immutable.Range.Inclusive
required: Int
val s = sum(1 to 5)
^
1
2
3
4
5
6
2
3
4
5
6
这种情况必须在后面写上: _* 将 1 to 5 转化为参数序列
scala> val s = sum(1 to 5: _*)
s: Int = 15
1
2
2
# 6.2 变量声明中的模式
下面代码分别将 arr 中的第一个和第二个值赋给 first 和 second
scala> val arr = Array(1,2,3,4,5)
arr: Array[Int] = Array(1, 2, 3, 4, 5)
scala> val Array(first, second, _*) = arr
first: Int = 1
second: Int = 2
1
2
3
4
5
6
2
3
4
5
6
# 7. 用于简写函数
如果函数的参数在函数体内只出现一次,则可以使用下划线代替:
val list = List(1,2,3,4)
list.foreach(println(_))
//等价于
list.foreach(x => println(x))
list.filter(_ > 1)
//等价于
list.filter(x => x > 1)
val sum1 = (x:Int,y:Int) => x + y
//等价于
val sum2 = (_:Int) + (_:Int)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 8. 类型通配符
Java的泛型系统有一个通配符类型,例如List<?>
,任意的List类型都是List<?>
的子类型,如果我们想编写一个可以打印所有List类型元素的方法,可以如下声明:
public static void printList(List<?> list){
list.forEach(System.out::println);
}
1
2
3
2
3
对应的Scala版本为:
def printList(list: List[_]): Unit ={
list.foreach(println)
}
1
2
3
2
3
# 9. 定义偏函数
对某个多参数函数进行部分函数调用,没有传入的参数使用_代替,返回结果即为偏函数。例:
def sum(a:Int,b:Int): Int ={
a + b
}
def main(args: Array[String]): Unit = {
val s = sum(1 , _:Int) //s就是偏函数,绑定第一个 a 参数,第二个参数使用下划线 _ 替换缺失的参数列表
println(s(2))
}
1
2
3
4
5
6
7
2
3
4
5
6
7
编辑 (opens new window)
上次更新: 2024/04/19, 08:52:45
- 01
- idea 热部署插件 JRebel 安装及破解,不生效问题解决04-10
- 02
- spark中代码的执行位置(Driver or Executer)12-12
- 03
- 大数据技术之 SparkStreaming12-12