Scala 下划线
1、概述
下划线这个符号在不同的场景下具有不同的含义。
2、替换Java的等价语法
大部分的Java语言的关键字在Scala语言中拥有了新的含义,所以一些基本的语法在Scala中有变化。
体现在导入通配符、类成员默认值、 可变参数、类型通配符等方面。
(1)导入通配符
*在Scala中是合法的方法名,所以导入包时要使用_代替。
//Java
import java.lang.*;
//Scala
import java.lang._
(2)类成员默认值(该语法只适用于类成员,而不适用于局部变量)
在Java中,类成员可以不赋初始值,因为编译器会自动帮你设置一个合适的初始值。
class Food{
String x;//String类型的默认值为null
}
在Scala中,你必须要显式指定,如果你不想设置,可以用_让编译器自动帮你设置初始值。
class Food{
//String类型的默认值为null
var s: String = _
}
(3)可变参数
Java声明可变参数:
public static void avgs(String ... args){
for(Object elememt: args){
System.out.println(elememt+ "|||");
}
}
//调用
//传入两个参数
avgs("x", "y");
//也可以传入一个数组
avgs(new String[]{"x", "y"});
在Java中,你可以直接将数组传给printArgs方法,但是在Scala中,你必须要明确地告诉编译器,你是想将集合作为一个独立的参数传进去,还是想将集合的元素传进去。如果是后者则要借助下划线:
avgs(List("x", "y"): _*)
(4) 类型通配符
在Java语言中,泛型系统有一个通配符类型,例如List<?>,任意的List<T>类型都是List<?>的子类型,如果我们想编写一个可以打印所有List类型元素的方法,可以声明如下:
public static void generateList(List<?> list){
for(Object element: list){
System.out.println(element+ "||||");
}
}
在Scala语言中,可声明如下:
def generateList(list: List[_]): Unit ={
list.foreach(elememt => println(elememt + "||||"))
}
3、模式匹配
(1)默认匹配
strs match{
case "666" => println("match 666")
case _ => println("match default")
}
(2)匹配集合元素
//匹配以6开头,长度为4的列表
expr match {
case List(6, _, _, _) => println("找到了")
case _ =>
}
//匹配以6开头,长度任意的列表
expr match {
case List(0, _*) => println("找到了")
case _ =>
}
//匹配元组元素
expr match {
case (6, _) => println("找到了")
case _ =>
}
//将首元素赋值给head变量
val List(head, _*) = List("x")
4、Scala特有语法
(1)访问Tuple元素
val x = (11, 12, 13)
println(x._1, x._2, x._3)
(2)简写函数字面量(function literal)
如果函数的参数在函数体内只出现一次,则可以使用下划线代替:
val m1 = (_: Int) + (_: Int)
//等价于
val m2 = (a: Int, b: Int) => a + b
list.foreach(println(_))
//等价于
list.foreach(x => println(x))
list.filter(_ > 6)
//等价于
list.filter(e => e > 6)
(3)定义一元操作符
在Scala语言中,操作符其实就是方法,例如2 + 2等价于2.+(2),利用下划线我们可以定义自己的左置操作符,例如Scala语言中的负数就是用左置操作符实现的:
-3
//等价于
3.unary_-
(4)定义赋值操作符
通过下划线实现赋值操作符,从而可以精确地控制赋值过程。
class Food{
def name = { "vegetable" }
def name_=(x: String) {
println("设置名字为" + x)
}
//等价于: food.name_=("tomcato")
val food = new Food()
food.name = "tomcato"
(5)定义部分应用函数
partially applied function,我们可以为某个函数只提供部分参数进行调用,返回的结果是一个新的函数,即部分应用函数。因为只提供了部分参数,所以部分应用函数也因此而得名:
def sum(x: Int, y: Int, z: Int) = x + y + z
val bb = sum(11, _: Int, 13)
bb: Int => Int = <function1>
bb(12) //36
(6)将方法转换成函数
Scala中方法和函数是两个不同的概念,方法无法作为参数进行传递,也无法赋值给变量,但是函数是可以的。
//将pointInfo方法转换成函数,并赋值给x
val x = pointInfo _
//x: (Any) => Unit