Scala基礎 - 下劃線使用指南

下劃線這個符號幾乎貫穿了任何一本Scala編程書籍,而且在不一樣的場景下具備不一樣的含義,繞暈了很多初學者。正因如此,下劃線這個特殊符號無形中增長Scala的入門難度。本文但願幫助初學者踏平這個小山坡。java

1. 用於替換Java的等價語法

因爲大部分的Java關鍵字在Scala中擁有了新的含義,因此一些基本的語法在Scala中稍有變化。編程

1.1 導入通配符

*在Scala中是合法的方法名,因此導入包時要使用_代替。數組

//Java
import java.util.*;

//Scala
import java.util._

1.2 類成員默認值

Java中類成員能夠不賦初始值,編譯器會自動幫你設置一個合適的初始值:app

class Foo{
     //String類型的默認值爲null
     String s;
}

而在Scala中必需要顯式指定,若是你比較懶,能夠用_讓編譯器自動幫你設置初始值:函數

class Foo{
    //String類型的默認值爲null
    var s: String = _
}

該語法只適用於類成員,而不適用於局部變量。spa

1.3 可變參數

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"): _*)

1.4 類型通配符

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 + " "))
}

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 定義部分應用函數(partially applied function)

咱們能夠爲某個函數只提供部分參數進行調用,返回的結果是一個新的函數,即部分應用函數。由於只提供了部分參數,因此部分應用函數也所以而得名。

def sum(a: Int, b: Int, c: Int) = a + b + c
val b = sum(1, _: Int, 3)
b: Int => Int = <function1>
b(2) //6

3.6 將方法轉換成函數

Scala中方法和函數是兩個不一樣的概念,方法沒法做爲參數進行傳遞,也沒法賦值給變量,可是函數是能夠的。在Scala中,利用下劃線能夠將方法轉換成函數:

//將println方法轉換成函數,並賦值給p
val p = println _  
//p: (Any) => Unit

4. 小結

下劃線在大部分的應用場景中是以語法糖的形式出現的,能夠減小擊鍵次數,而且代碼顯得更加簡潔。可是對於不熟悉下劃線的同窗閱讀起來稍顯困難,但願經過本文可以幫你解決這個的困惑。本文成文倉促,若有遺漏,歡迎留言! 轉載請註明做者: joymufeng

相關文章
相關標籤/搜索