1、用于替换java的等价语法
1.1 导入通配符
*在scala中是合法的方法名,所以导入包时使用_代替
//Java
import java.util.*
//scala
import java.util._
1.2 类成员默认值
Java中类成员可以不赋初始值,编译器会自动帮你设置一个合适的初始值
class test{
String s;
}
而在scala中必须显式指定,如果不指定,可以用_让编译器自动帮你设置初始值
class test{
var s:String = _
}
该语法只适用于类成员,而不适用于局部变量
1.3 可变参数
scala中实现一个可以接受可变长度参数列表的函数
def sum(args:Int*){
var result = 0
for (arg <- args) result += arg
result
}
可以使用任意多的参数来调用该函数
val s = sum(1,2,3,4)
函数得到的是一个类型为Seq的参数。如果你已经有一个值的序列,则不能直接将它传入上述函数。如下的写法是不对的:
val s = sum(1 to 5)//错误
如果sum函数被调用时传入的是单个参数,那么该参数必须是单个整数,而不是一个整数区间。解决这个问题的办法是告诉编译器你希望这个参数被当作参数序列处理。追加:_*即可。
val s = sum(1 to 5:_*)
1.4 类型通配符
Java的泛型系统有一个通配符类型,例如List
public static void printList(List<?> list){
for(Obiect elem:list){
System.out.println(elem + " ")
}
}
对应的scala版本是:
def printList(list:List[_]): Uint ={
list.foreach(elem => println(elem + " "))
}
2、模式匹配
2.1 默认匹配
str match{
case "1" => println("match 1")
case _ => println("match default")
}
2.2 匹配集合元素
//匹配以0开头,长度为三的列表
expr match {
case List(0,_,_) => println("found it")
case _ =>
}
//匹配以0开头,长度任意的列表
expr match {
case List(0,_,*) => println("found it")
case _ =>
}
//匹配元组元素
expr match {
case (0,_) => println("found it")
case _ =>
}
//将首元素赋值给head变量
val List(head, _*) = List("a")
3、scala特有语法
3.1 访问Tuple元素
val t = (1,2,3)
println(t._1, t._2, t._3)
3.2 简写函数字面量(function literal)
如果函数的参数在函数体只出现一次,则可以使用下划线代替:
val f1 = (_: Int) + (_: Int)
//等价于
val f2 = (x: Int, y: Int) => x + y
list.foreach(println(_))
//等价于
list.foreach(e => println(e))
list.filter(_ > 0)
//等价于
list.filter(x => x > 0)
3.3 定义一元操作符
在scala中,操作符其实就是方法,例如1+1等价于1.+(1),利用下划线我们可以定义自己的左置操作符,例如scala中的负数就是用左置操作符实现的:
-2
//等价于
2.unary_-
3.4 定义赋值操作符
通过下划线实现赋值操作符,从而可以精确地控制赋值过程
class Foo{
def name = {"Foo"}
def name_= (str:String) {
println("set name " + str)
}
}
val m = new Foo()
m.name = "Foo" //等价于m.name_= ("Foo")
3.5 定义部分应用函数
可以为某个函数只提供部分参数进行调用,返回的结果是一个新的函数,即部分应用函数。因为只提供了部分参数,所以部分应用函数也因此得名。
def sum(a: Int,b: Int,c: Int) = a + b + c
val b = sum(1, _: Int, 3)
b(2) //6
3.6 将方法转换成函数
scala中方法和函数是两个不同的概念,方法无法作为参数进行传递,也无法赋值给变量,但是函数是可以的。在scala中,利用下划线可以将方法转换成函数:
//将println方法转换成函数,并赋值给p
val p = println _
//p: (Any) => Unit