scala的樣本序列——不和match一起使用的case序列

case樣本序列

先看一段代碼

    val func1: Int => Int = {
        case x  => 1
    }

等號的右邊是{case x => 1},一對花括號包裹着一個case語句。這樣的用法看到過很多次,但是很少有資料解釋爲什麼可以這樣用。查閱過很多資料,最終在《programming in Scala》(scala編程:黃海旭,高宇翔譯)裏出現過一段話。“樣本序列可以用在出現函數字面量的任何地方。實質上,樣本序列就是函數字面量,而且更普遍。函數字面量有一個入口點和參數列表,但是樣本序列可以有多個入口點,每個都有自己的參數列表。”這三句話總結起來有兩點:

  1. 樣本序列可以替代函數字面量使用
  2. 樣本序列和一般函數字面量的不同在於有多個入口點,每個入口點有自己獨立的參數列表

現在就可以解釋爲什麼在代碼中可以這樣使用了,首先 val func1: Int => Int 聲明瞭不可變變量要被賦值一個Int => Int 類型的函數字面量,所以{case x => 1}可以被賦值給func1。
這種用法在scala裏十分常見。大家一定經常使用的函數如foreach():

         def foreach[U](f: A => U) { while (hasNext) f(next()) }

大家習慣性的使用方式是:

		Seq(1, 2, 3).foreach{case x => println(x)}

這是因爲foreach要求使用一個A => U類型的函數字面量作爲參數,所有可以使用樣本序列{case x => println(x)}作爲參數。而上面的代碼其實是一種縮寫,實際上應該是:

		Seq(1, 2, 3).foreach({case x => println(x)}) //比上面的代碼多了一對括號()

此外,如大家常用的操作,如map,reduce都可以用樣本序列替換函數字面量。
以上展示的都是單行樣本序列,然後還有多行樣本序列,原理都是一樣的。

一個問題?

scala中還有一個不常用的寫法:

        val func2: Int => Int = {
            x => 1
        }

這種寫法和上面的上面的寫法幾乎一模一樣,唯獨少量一個case,不知道是不是樣例類的一種簡寫。如果有知道的還請解釋一下。我個人覺得有可能是閉包.

之前留了一個疑問,現在對這個疑問做下解釋:
其實上面的例子很簡單,只是一直陷入思維慣性,覺得很高深。我們在scala裏是可以直接定義匿名函數的,如:
在這裏插入圖片描述

現在我們考慮給這個匿名函數賦給一個值:

	val func2 = (x:Int) => 1+x

然後大家應該記得scala的代碼塊,就是花括號連同它包裹的地方是有值得,他的值就是最後一句代碼所標識的值,那{(x:Int) => 1+x}的值就是(x:Int) => 1+x,那麼上一句代碼就可以表示爲:

	val func2 = {
			(x:Int) => 1+x
	}

然後只需要聲明一下fun2的類型:

        def func2:Int => Int = {
            (x:Int) => 1+x 
        }

然後做一下縮寫,如去掉花貨號裏的()和x的數據類型聲明:

        def func2:Int => Int = {
            x: => 1+x
        }

現在就得到了最初的形式。爲了進一步驗證正確性,可以嘗試在花括號里加一些代碼,發現也是可行的。

        def func2: Int => Int = {
            val y = 10
            x: => 1 + x + y
        }

然後我們嘗試在代碼塊的最後加一些代碼:

        def func2: Int => Int = {
            val y = 10
            x => 1 + x + y
            val z = 0
            z
        }

發現這樣也是可行的,按理說這樣應該不可以,因爲代碼塊的最後一句是一個z代碼的是一個Int類型,並不是 Int => Int類型的函數字面量。這是因爲上面呢的代碼產生了視覺誤差,實際上應該是下面這樣的。

        def func2: Int => Int = {
            val y = 10
            x =>1 + x + y
                val z = 0
                z
        }
最後兩句代碼是屬於Int=>Int這個方法的方法體的
            x =>{1 + x + y
                val z = 0
                z}

然後嘗試把最後兩句代碼從裏面的函數的方法體裏取出來,就會報錯:

        def func2: Int => Int = {
            val y = 10
            { x => 1 + x + y }
            val z = 0
            z
        }

Error:(9, 13) type mismatch;
found : Int
required: Int => Int
z

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章