1. 程式人生 > >Scala系列——Scala中_(下劃線)的常見用法

Scala系列——Scala中_(下劃線)的常見用法

將方法轉換為函式

scala> def ml(x: Int,y:Int) : Int= x*y
scala> val f1=m1 _

作為函式的引數

        一個匿名的函式傳遞給一個方法或者函式的時候,scala會盡量推斷出引數型別。例如一個完整的匿名函式作為引數可以寫為

scala> def compute(f: (Double)=>Double) = f(3)
compute: (f: Double => Double)Double
​
//傳遞一個匿名函式作為compute的引數
scala> compute((x: Double) => 2 * x)
res1: Double = 6.0

如果引數x在=>右側只出現一次,可以用_替代這個引數,簡寫為

scala> compute(2 * _)
res2: Double = 6.0

更常見的使用方式為

scala> (1 to 9).filter(_ % 2 == 0)
res0: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8)
​
scala> (1 to 3).map(_ * 3)
res1: scala.collection.immutable.IndexedSeq[Int] = Vector(3, 6, 9)

以上所說的為一元函式,那麼對於二元函式,即有兩個引數x和y的函式,是如何使用_的?可以參考sortWith方法的定義

def sortWith(lt: (T, T) ⇒ Boolean): Array[T]

        這個方法的引數官方解釋為 the comparison function which tests whether its first argument precedes its second argument in the desired ordering.

        這個方法需要的引數是一個二元函式,而且函式引數的型別為T,例如

scala> List(10, 5, 8, 1, 7).sortWith(_ < _)
res0: List[Int] = List(1, 5, 7, 8, 10)

可以用_分別表示二元函式中的引數x和y。

作為識別符號

        例如定義一個變數val _num = 123

作為萬用字元

import語句,例如:

import scala.math._

case語句,例如:

object MatchTest extends App {
  def matchTest(x: Int): String = x match {
    case 1 => "one"
    case 2 => "two"
    case _ => "many"
  }
  println(matchTest(3))
}

元組(tuple),例如:

//可以定義一個tuple
scala> val t = (1, 3.14, "Fred")
t: (Int, Double, String) = (1,3.14,Fred)
//可以用_1,_2,_3訪問這個元組
scala> t._1
res3: Int = 1
​
scala> t._2
res4: Double = 3.14
​
scala> t._3
res5: String = Fred

可以通過模式匹配獲取元組的元素,當不需要某個值的時候可以使用_替代,例如

scala> val t = (1, 3.14, "Fred")
t: (Int, Double, String) = (1,3.14,Fred)
​
scala> val (first, second, _) = t
first: Int = 1
second: Double = 3.14
​
scala> val (first, _, _) = t
first: Int = 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

但是如果使用這種方式就會報錯

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 to 5轉化為引數序列

scala> val s = sum(1 to 5: _*)
s: Int = 15
  • 變數宣告中的模式

     例如,下面程式碼分別將arr中的第一個和第二個值賦給first和second

scala> val arr = Array(1,2,3,4,5)
arr: Array[Int] = Array(1, 2, 3, 4, 5)
​
scala> val Array(1, 2, _*) = arr
​
scala> val Array(first, second, _*) = arr
first: Int = 1
second: Int = 2