Scala學習十八——高級類型


一.本章要點

  • 單例類型可用於方法串接和帶對象參數的方法  
  • 類型投影對所有外部類的對象都包含了其他內部類的實例
  • 類型別名給類型指定一個短小的名稱
  • 結構類型等效於”鴨子類型“
  • 存在類型為泛型的通配參數提供了統一形式
  • 使用自身類型來表明某特質對混入它的類或對象的類型要求
  • ”蛋糕模式“用自身類型來實現依賴注入
  • 抽象類型必須在子類中具體化
  • 高等類型帶有本身參數化類型的類型參數

二.單例類型

  給定任何引用v,可以得到類型.type,可能的兩個值:v和null。例:

//通過this返回自身串接
class Document{
def setTitle(title:String)={...;this}
def serAuthor(author:String)={...;this}
...
}

article.setTile("...").setAuthor("...")

//有子類
class Book extends Document{
def addChapter(chapter:String)={...;this}
}
val book=new Book()
book.setTile("...").addChapter("...")//setTitle返回類型推斷為Document,沒有addChapter方法
//解決(需要this.type)
def setTitle(title:String):this.type={...;this}

三.類型投影

   

   像這樣,嵌套類從屬於包含它的外部對象,每個Metwork實例都有自己的Member類(是不同的,不能將成員相互添加),不想要這個約束可以是放在伴生對象。

   如果不是所有地方都使用”每個對象自己的內部類“,可以使用類型投影,Network#Member。。。

 

 

四.路徑

  定位一個類等的位置。路徑的組成必須是”穩定的“,必須指定單個,有窮的范圍,組成部分是(包,對象,val,[this、super、super[S]、C.this、C.super[S]])中的一種,路徑組成部分不能是類。

  注:路徑組成部分不能是類(嵌套的內部類型並不是單個類型);

    在內部,編譯器將嵌套的表達式a.b.c.T翻譯稱類型投影a.b.c.type#T。。。      

五.類型別名

  對於復雜類型,可以用type關鍵字創建一個簡單的別名。例:

    

class Book{
import scala.collection.mutable._
//可以直接用Book.Index而不是scala.collection.mutable.HashMap[String,(Int.Int)]
type Index=HashMap[String,(Int,Int)]
}

 

  注:類型別名必須被嵌套在類或對象中,不能呢個出現在Scala文件頂層(在REPL中可以,REPL中的內容都隱藏在一個頂層對象中)

六.結構類型(類似於鴨子類型)

  指的是一組關於抽象方法,字段和類型規格說明(必須的)。

  

  任何具備append方法的類的實例調用appendLines方法,比定義一個特質更靈活(可能不能夠總是將特質添加到類上),結構類型實際是Scala利用反射調用target.append(...),反射比常規方法調用開銷大得多(對無法共享一個特質的類的共通行為才使用結構類型)。

七.復合類型

  定義形式為T1 with T2 with T3...,其中T1,T2等都是類型,要想成為該復合類型的實例,必須滿足每一個類型(稱為交集類型)。

八.中置類型

  中置類型是一個帶有兩個類型參數的類型,以”中置“表示,類型名稱寫在兩個類型參數中間。,如String Map Int而不是Map[String,Int],又如type x(A,B)=(A,B)。。。

九.存在類型

  存在類型是為了與Java的類型通配符兼容,在類型表達式后跟forSome{...},花括號包含了type和val聲明,如:Array[T] forSome{type T<:JComponent}。。。

十.Scala類型系統

十一.自身類型

  通過this:類型=>限制這樣的特質只能混入給定類型的子類當中。

十二.依賴注入

  通過組件構建大型系統時,每個組件都有不同的實現,需要將組件的不同選擇組裝起來。

  組件之間存在某種依賴關系,在Scala中,通過特質和自身類型達到一個簡單的依賴注入的效果。

  使用蛋糕模式,為每個服務都提供一個組件特質:

 

 

 

 

十三.抽象類型

  類和特質可以定義在一個子類中被具體化的抽象模型,例:

 

   比較:

    如果類型是在類被實例化時給出,則使用類型參數。比如構造HashMap[String,Int];

    如果類型是在子類中給出的,則使用抽象類型。

十四.家族多態

  對跟着一起變化的類型家族建模,同時共用代碼,並保持線程安全。。。

十五.高等類型

  泛型List依賴於類型T並產出一個特定的類型,像List這樣的泛型叫類型構造器,在Scala中,可以更上一層,定義依賴於依賴其他類型的類型的類型。

十六.練習

 

 

 

 

 

 


免責聲明!

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



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