【scala】占位符


Scala語言為了讓函數字面量更加精簡,還可以使用下划線作為占位符,用來表示一個或多個參數

我們用來表示的參數必須滿足只在函數字面量中出現一次。

我們用例子來看占位符的用法

scala> val list = List(1,2,3,4,5)
list: List[Int] = List(1, 2, 3, 4, 5)

scala> list.filter( _ > 3 )//等同於 x => x > 3
res0: List[Int] = List(4, 5)

我們看到 _ 就好像是表達式中需要被填入的空,函數每次調用的時候這個空就被一個傳入參數填上

但是參數是依次填入的,不能重復。也就是說,像上例的 1,2,3,4,5.並不能從頭再來依次。

scala> val nums = List(1,2,3,4,5)
nums: List[Int] = List(1, 2, 3, 4, 5)

scala> nums.map((_,1)) //等同於 x => (x,1)
res1: List[(Int, Int)] = List((1,1), (2,1), (3,1), (4,1), (5,1))

當然,我們也可以使用多個占位符來表示多個參數。

scala> val nums = List(1,2,3,4,5)
nums: List[Int] = List(1, 2, 3, 4, 5)

scala> nums.reduce( _+_ ) //相當於 a + b
res2: Int = 15

上例中,第一個占位符代表一個參數,第二個代表不同於第一個的參數。

執行過程是這樣的,先第一個參數 1 填上第一個占位符,第二個參數 2 填入第二個占位符,注意這里並不是參數列表從新填一次。

執行1+2 = 3.因為reduce,3重新排入list中,list現在為3,3,4,5

然后再次填入,3 + 3,list中變為 6,4,5

依次類推。結果為 15.

但是注意,我們在使用占位符的時候,編譯器可能並沒有足夠的信息區推斷你缺失的類型

使用的時候不要盲目的省略,避免造成不必要的錯誤。

scala> val f = _ + _
<console>:11: error: missing parameter type for expanded function ((x$1: <error>, x$2) => x$1.$plus(x$2))
       val f = _ + _
               ^
<console>:11: error: missing parameter type for expanded function ((x$1: <error>, x$2: <error>) => x$1.$plus(x$2))
       val f = _ + _
                   ^

上面的例子就是,我們在定義 f 方法的時候只用了占位符來表示兩個參數,但是編譯器並不能推斷出你的參數類型,報錯。

這個時候我們需要注明參數類型

scala> val f = (_:Int) + (_:Int)
f: (Int, Int) => Int = $$Lambda$1108/2058316797@4a8bf1dc

scala> f(1,2)
res5: Int = 3

為什么我們開始的例子不用注明參數類型呢?因為我們在創建List的時候指明了類型為List[Int] 也就是編譯器知道每個參數都為Int

注意,當使用多個占位符的時候,代表的是不同的參數,不能是相同的參數。

占位符也可以代替一個參數列表

scala> def sum(a:Int,b:Int,c:Int) = a+b+c
sum: (a: Int, b: Int, c: Int)Int

scala> val a = sum _
a: (Int, Int, Int) => Int = $$Lambda$1137/810864083@755a4ef5

我們這里用了一個占位符代替了sum方法的參數列表,注意方法和占位符之間要有個空格,因為scala語言中方法名可以定義這樣:sum_ 。

我們在創建方法的時候並不能用占位符來代替參數列表,編譯器並不能推斷出占位符代表的東西。

只能用占位符來代替已經明確的東西,也就是說來代替已經定義好的方法的參數列表。

scala> val b = sum(1,_:Int,3)
b: Int => Int = $$Lambda$1138/1122185195@3652dd19

scala> b(2)
res6: Int = 6

我們還可以這么用,用占位符來代替其中的一個參數,然后調用的時候只需要傳入一個參數即可。

注意,這里代替的時候輸出初始化一個參數,必須要表明參數類型。

當然有的時候我們還可以更省略,不過只能用在明確需要函數的時候。

scala> list.foreach(println _)
1
2
3
4
5

scala> list.foreach(println)
1
2
3
4
5

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM