下划线这个符号几乎贯穿了任何一本Scala编程书籍,而且在不一样的场景下具备不一样的含义,绕晕了很多初学者。正因如此,下划线这个特殊符号无形中增长Scala的入门难度。本文但愿帮助初学者踏平这个小山坡。java
因为大部分的Java关键字在Scala中拥有了新的含义,因此一些基本的语法在Scala中稍有变化。编程
*在Scala中是合法的方法名,因此导入包时要使用_代替。数组
//Java import java.util.*; //Scala import java.util._
Java中类成员能够不赋初始值,编译器会自动帮你设置一个合适的初始值:app
class Foo{ //String类型的默认值为null String s; }
而在Scala中必需要显式指定,若是你比较懒,能够用_让编译器自动帮你设置初始值:函数
class Foo{ //String类型的默认值为null var s: String = _ }
该语法只适用于类成员,而不适用于局部变量。spa
Java声明可变参数以下:code
public static void printArgs(String ... args){ for(Object elem: args){ System.out.println(elem + " "); } }
调用方法以下:编译器
//传入两个参数 printArgs("a", "b"); //也能够传入一个数组 printArgs(new String[]{"a", "b"});
在Java中能够直接将数组传给printArgs方法,可是在Scala中,你必需要明确的告诉编译器,你是想将集合做为一个独立的参数传进去,仍是想将集合的元素传进去。若是是后者则要借助下划线:it
printArgs(List("a", "b"): _*)
Java的泛型系统有一个通配符类型,例如List<?>,任意的List<T>类型都是List<?>的子类型,若是咱们想编写一个能够打印全部List类型元素的方法,能够以下声明:io
public static void printList(List<?> list){ for(Object elem: list){ System.out.println(elem + " "); } }
对应的Scala版本为:
def printList(list: List[_]): Unit ={ list.foreach(elem => println(elem + " ")) }
str match{ case "1" => println("match 1") case _ => println("match default") }
//匹配以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")
val t = (1, 2, 3) println(t._1, t._2, t._3)
若是函数的参数在函数体内只出现一次,则可使用下划线代替:
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)
在Scala中,操做符其实就是方法,例如1 + 1等价于1.+(1),利用下划线咱们能够定义本身的左置操做符,例如Scala中的负数就是用左置操做符实现的:
-2 //等价于 2.unary_-
咱们经过下划线实现赋值操做符,从而能够精确地控制赋值过程:
class Foo { def name = { "foo" } def name_=(str: String) { println("set name " + str) } val m = new Foo() m.name = "Foo" //等价于: m.name_=("Foo")
咱们能够为某个函数只提供部分参数进行调用,返回的结果是一个新的函数,即部分应用函数。由于只提供了部分参数,因此部分应用函数也所以而得名。
def sum(a: Int, b: Int, c: Int) = a + b + c val b = sum(1, _: Int, 3) b: Int => Int = <function1> b(2) //6
Scala中方法和函数是两个不一样的概念,方法没法做为参数进行传递,也没法赋值给变量,可是函数是能够的。在Scala中,利用下划线能够将方法转换成函数:
//将println方法转换成函数,并赋值给p val p = println _ //p: (Any) => Unit
下划线在大部分的应用场景中是以语法糖的形式出现的,能够减小击键次数,而且代码显得更加简洁。可是对于不熟悉下划线的同窗阅读起来稍显困难,但愿经过本文可以帮你解决这个的困惑。本文成文仓促,若有遗漏,欢迎留言! 转载请注明做者: joymufeng