Scala Types 1

在 Scala 中所有值都有一種對(duì)應(yīng)的類型

單例類型

  • 形式:value.type,返回類型 value / null

  • 場(chǎng)景1:鏈?zhǔn)紸PI調(diào)用時(shí)的類型指定

    class Super {
      def m1(t: Int) = {println(t); this}
      def m2(t: Int) = {println(t); this}
    }
    // 正常打印
    new Super().m1(1).m2(2)
    
    class Child extends Super {
      def c1(t: Int) = {println(t); this}
    }
    
    // 異常  value c1 is not a member of Super
    new Child().m1(1).c1(2)
    

    由于 Scala 會(huì)將 this 推斷為當(dāng)前類(即 Super)糠雨,因此無法完成鏈?zhǔn)秸{(diào)用

    class Super {
      // 指定返回類型為調(diào)用方的 this 
      def m1(t: Int): this.type = {println(t); this}
      def m2(t: Int): this.type = {println(t); this}
    }
    
    class Child extends Super {
      def c1(t: Int) = {println(t); this}
    }
    
    // 成功打印
    new Child().m1(1).c1(2)
    
  • 場(chǎng)景2:方法中使用 object 實(shí)例作為參數(shù)

    object Foo
    class Child extends Super {
      def c1(obj: Foo.type) = {
        if (obj == Foo) println("foo")
        this
      }
    }
    

    Note:不可定義為 def c1(obj: Foo)祥楣,因?yàn)?Foo 為單例對(duì)象娜睛,而不是類型

類型投影

  • 形式:Outer#Inner

  • 場(chǎng)景:內(nèi)部類使用時(shí)避免類型約束

    class Outer {
      private val inners = ArrayBuffer[Inner]()
    
      class Inner (val arg1: Int) {
        val l = ArrayBuffer[Inner]()
      }
    
      def add(a: Int) = {
        val t = new Inner(a)
        inners += t
        t
      }
    }
    
    val a = new Outer
    val b = new Outer
    
    val a1 = a.add(1)
    val b1 = b.add(1)
    a1.l += b1 // error: type mismatch;
    

    只需要在定義內(nèi)部類時(shí)指定類型投影即可解決

    // 表示適用于任何 Outer 類的 Inner 類
    val l = ArrayBuffer[Outer#Inner]()
    

    如果將上述例子改用 List 來實(shí)現(xiàn)鼓拧,并不會(huì)報(bào)錯(cuò)谍倦,計(jì)算結(jié)果也會(huì)自動(dòng)進(jìn)行類型投射

路徑

  • 路徑中除最后一部分外耍铜,都必須是穩(wěn)定狀態(tài)的邑闺,如包名、object业扒、val检吆、this/super/super[S]...

  • 不能包含 var 類型

    var t = new Outer()
    //...其他操作
    val i = new t.Inner // 由于 t 可能會(huì)變更舒萎,編譯器無法確定其含義
    

    a.b.c.T 內(nèi)部被翻譯成類型投射 a.b.c.type#T

類型別名

  • 形式: type SomeAliasName

  • 必須定義在 classobject 內(nèi)部

  • 好處: 在引用類型時(shí)可以更加簡(jiǎn)潔

    class Book {
      import scala.collection.mutable._
      // 為該類型取一個(gè)別名
      type Index = HashMap[String, Int]
      
      // 使用時(shí)不在需要重復(fù)的定義復(fù)雜的數(shù)據(jù)類型
      val map: Index = new Index()
    }
    
    new Book().map  // scala.collection.mutable.HashMap[String,Int]
    

結(jié)構(gòu)類型

  • 為抽象方法程储、字段蹭沛、類型的定義某種規(guī)范

    def appendLines(target: { def append(str: String): Any },
      lines: Iterable[String]) {
      for (l <- lines) { 
        // 此次 Scala 使用反射調(diào)用該方法
        target.append(l); 
        target.append("\n") 
      }
    }
    

    該方法第一個(gè)參數(shù) target 即結(jié)構(gòu)類型,表示使用任何包含該 append 方法的實(shí)例作為參數(shù)傳入章鲤。

    由于反射的代價(jià)較大摊灭,不到萬不得已不建議使用,如败徊,有通用行為(append)帚呼,卻無法共享 trait

組合類型 / 交集類型

  • 形式: T1 with T2 with T3 ...

  • 當(dāng)需要提供多個(gè)特質(zhì)時(shí)使用,即用于約束類型

    val image = new ArrayBuffer[java.awt.Shape with java.io.Serializable]
    val rect = new Rectangle(5, 10, 20, 30)
    image += rect // 正確皱蹦,Rectangle 可序列化
    image += new Area(rect) // 錯(cuò)誤 Area 不可序列化
    
  • 組合類型中也可使用結(jié)構(gòu)類型

    Shape with Serializable { def contains(p: Point): Boolean }
    

中綴類型

  • 其實(shí)只是一種語法寫法煤杀,如 String Map Int 可代替 Map[String, Int]

  • 可參考數(shù)學(xué)運(yùn)算中的表達(dá)方式

    type x[A, B] = (String, Int)
    // 即可使用 String x Int 來表示 (String, Int)
    
  • 一般中綴類型操作符都是左關(guān)聯(lián)的,除了前面提到的 : 操作符沪哺,這個(gè)是右關(guān)聯(lián)的沈自,比如 List 的操作

中綴類型名稱可以是任意操作符,除了 *辜妓,避免與類型定義沖突

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末枯途,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子籍滴,更是在濱河造成了極大的恐慌酪夷,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件孽惰,死亡現(xiàn)場(chǎng)離奇詭異晚岭,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)勋功,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門腥例,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人酝润,你說我怎么就攤上這事燎竖。” “怎么了要销?”我有些...
    開封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵构回,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我疏咐,道長(zhǎng)纤掸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任浑塞,我火速辦了婚禮借跪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘酌壕。我一直安慰自己掏愁,他們只是感情好歇由,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著果港,像睡著了一般沦泌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辛掠,一...
    開封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天谢谦,我揣著相機(jī)與錄音,去河邊找鬼萝衩。 笑死回挽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的猩谊。 我是一名探鬼主播厅各,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼预柒!你這毒婦竟也來了队塘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤宜鸯,失蹤者是張志新(化名)和其女友劉穎憔古,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體淋袖,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鸿市,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了即碗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片焰情。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖剥懒,靈堂內(nèi)的尸體忽然破棺而出内舟,到底是詐尸還是另有隱情,我是刑警寧澤初橘,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布验游,位于F島的核電站,受9級(jí)特大地震影響保檐,放射性物質(zhì)發(fā)生泄漏耕蝉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一夜只、第九天 我趴在偏房一處隱蔽的房頂上張望垒在。 院中可真熱鬧,春花似錦扔亥、人聲如沸场躯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽推盛。三九已至,卻和暖如春谦铃,著一層夾襖步出監(jiān)牢的瞬間耘成,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工驹闰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瘪菌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓嘹朗,卻偏偏與公主長(zhǎng)得像师妙,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子屹培,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361