Scala 深刻淺出實戰經典 第51講:Scala中鏈式調用風格的實現代碼實戰及其在Spark中應用

王家林親授《DT大數據夢工廠》大數據實戰視頻 Scala 深刻淺出實戰經典(1-64講)完整視頻、PPT、代碼下載:
百度雲盤:http://pan.baidu.com/s/1c0noOt6
騰訊微雲:http://url.cn/TnGbdC
360雲盤:http://yunpan.cn/cQ4c2UALDjSKy 訪問密碼 45e2
土豆:http://www.tudou.com/programs/view/5uuKOP38d6s/
優酷:http://v.youku.com/v_show/id_XMTI4MzMzMjM3Ng==.html?from=s1.8-1-1.2
愛奇藝:http://www.iqiyi.com/w_19rrx5djod.html#vfrm=2-3-0-1
騰訊視頻: http://v.qq.com/boke/page/q/0/a/q01598mqrna.html
技術愛好者尤爲是大數據愛好者 能夠加DT大數據夢工廠的qq羣html

DT大數據夢工廠① :462923555
DT大數據夢工廠②:437123764
DT大數據夢工廠③ :418110145java

微信公衆帳號: DT_Spark
王家林老師微信號: 18610086859
王家林老師QQ: 1740415547
王家林老師郵箱: 18610086859@126.com微信

本視頻由王家林老師, 親自講解, 徹底經過代碼實戰把您帶人大數據的時代.大數據

package com.parllay.scala.type_parameterizitor

/**
* Created by richard on 15-8-5.
* 第51講:Scala中鏈式調用風格的實現代碼實戰及其在Spark中應用
*/
object Singleton_Type {
/**

scala> object A

scala> A.getClass
res2: Class[_ <: A.type] = class A$

scala> typeOf[A.type]
res0: reflect.runtime.universe.Type = A.type
對於這種單例,它的類型與它的類不一樣,要用 A.type 來表示。

這有點怪,一般咱們不會用它,好比下面的方式都畫蛇添足:

scala> val a : A.type = A

scala> def foo() : A.type = A
一方面由於scala有類型推導的功能,另外一方面,由於單例是惟一的,
A.type類型只有惟一的實例A(排除null),我須要的話直接用A就行了。

不過咱們討論的話題重點是 singleton type,想象一下A是一個對象實例,
是否對任何實例x都存在一個x.type這樣的類型呢?

scala> class A

scala> val a = new A

scala> typeOf[a.type]
res0: reflect.runtime.universe.Type = a.type
wow,真的存在。再用這個類型聲明一個變量看看:

scala> val x:a.type = a
x: a.type = A@6738694b
靈的,若是賦一個非a的實例呢?

scala> val x:a.type = a2
<console>:13: error: type mismatch;
found : a2.type (with underlying type A)
required: a.type

scala> typeOf[a.type] == typeOf[A] // a.type 與 A 不是同一個類型
res2: Boolean = false

scala> typeOf[a.type] == typeOf[a2.type] // a.type 與 a2.type 也不一樣
res1: Boolean = false

scala> typeOf[a.type] <:< typeOf[A] // a.type 是 A 類型的子類型
res5: Boolean = true
看到了,a.type 與 a2.type 是不一樣的類型!a.type也是單例類型,
它也只有惟一的實例: a (排除null)

全部的對象實例都有一個x.type的單例類型,它只對應當前對象實例。
這麼作有什麼意義呢?

從這裏看到一種狀況,在「鏈式」調用風格下,有適用的場景:

class A {def method1: A = this }
class B extends A {def method2: B = this}

val b = new B
b.method2.method1 // 能夠工做
b.method1.method2 // 不行,提示:error: value method2 is not a member of A
有些人很喜歡用 x.foo.bar 這樣的方式連續的去操做,這種風格也成爲」鏈式調用」風格,
它要求方法返回的必須是當前對象類型,以便連貫的調用方法。不過上面,
由於父類中聲明的method1方法返回類型限制死了就是A類型(不寫返回值類型,用類型推導也同樣),
致使子類對象調用完method1以後,類型已經變成了父類型,沒法再調用子類型中的方法了。解決方法是:

class A { def method1: this.type = this }
class B extends A { def method2 : this.type = this }

val b = new B
b.method1.method2 // ok
把返回類型都改成了 this.type 單例類型,就靈了。它利用了this關鍵字的動態特性來實現的,
在執行b.method1 的時候,method1返回值類型this.type 被翻譯成了B.this.type

scala> b.method1
res0: b.type = B@ca5bdb6
這樣不一樣的對象實例在執行該方法的時候,返回的類型也是不一樣的(都是當前實例的單例類型)。

小結,單例類型是個特殊的類型,單例類型綁定(依賴)在某個對象實例上,每一個對象實例都有它的單例類型。不過它的場景並很少見。
*/
}
相關文章
相關標籤/搜索