<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
泛型的意思是泛指某種具體的資料型別
, 在Scala中, 泛型用[資料型別]
表示. 在實際開發中, 泛型一般是結合陣列或者集合來使用的, 除此之外, 泛型的常見用法還有以下三種:
泛型方法指的是把泛型定義到方法宣告上, 即:該方法的引數型別是由泛型來決定的
. 在呼叫方法時, 明確具體的資料型別.
格式
def 方法名[泛型名稱](..) = { //... }
需求
定義方法getMiddleElement(), 用來獲取任意型別陣列的中間元素.
參考程式碼
//案例: 泛型方法演示. //細節: 泛型方法在呼叫方法的時候 明確具體的資料型別. object ClassDemo01 { //需求: 用一個方法來獲取任意型別陣列的中間的元素 //思路一:不考慮泛型直接實現(基於Array[Int]實現) //def getMiddleElement(arr: Array[Int]) = arr(arr.length / 2) //思路二: 加入泛型支援 def getMiddleElement[T](arr: Array[T]) = arr(arr.length / 2) def main(args: Array[String]): Unit = { //呼叫方法 println(getMiddleElement(Array(1, 2, 3, 4, 5))) println(getMiddleElement(Array("a", "b", "c"))) } }
泛型類指的是把泛型定義到類的宣告上, 即:該類中的成員的引數型別是由泛型來決定的
. 在建立物件時, 明確具體的資料型別.
格式
class 類[T](val 變數名: T)
需求
參考程式碼
//案例: 泛型-演示泛型類的使用. //泛型類: 在建立物件的時候, 明確具體的資料型別. object ClassDemo02 { //1. 實現一個Pair泛型類 //2. Pair類包含兩個欄位,而且兩個欄位的型別不固定 class Pair[T](var a:T, var b:T) def main(args: Array[String]): Unit = { //3. 建立不同型別泛型類物件,並列印 var p1 = new Pair[Int](10, 20) println(p1.a, p1.b) var p2 = new Pair[String]("abc", "bcd") println(p2.a, p2.b) } }
泛型特質指的是把泛型定義到特質的宣告上, 即:該特質中的成員的引數型別是由泛型來決定的
. 在定義泛型特質的子類或者子單例物件時, 明確具體的資料型別.
格式
trait 特質A[T] { //特質中的成員 } class 類B extends 特質A[指定具體的資料型別] { //類中的成員 }
需求
參考程式碼
//案例: 演示泛型特質. object ClassDemo03 { //1. 定義泛型特質Logger, 該類有一個a變數和show()方法, 都是用Logger特質的泛型. trait Logger[T] { //定義變數 val a:T //定義方法. def show(b:T) = println(b) } //2. 定義單例物件ConsoleLogger, 繼承Logger特質. object ConsoleLogger extends Logger[String]{ override val a: String = "張三" } //main方法, 作為程式的主入口. def main(args: Array[String]): Unit = { //3. 列印單例物件ConsoleLogger中的成員. println(ConsoleLogger.a) ConsoleLogger.show("10") } }
在使用泛型(方法, 類, 特質)時,如果要限定該泛型必須從哪個類繼承、或者必須是哪個類的父類別。此時,就需要使用到泛型的上下界
。
使用T <: 型別名
表示給型別新增一個上界,表示泛型引數必須要從該類(或本身)繼承.
格式
[T <: 型別]
例如: [T <: Person]的意思是, 泛型T的資料型別必須是Person型別或者Person的子型別
需求
參考程式碼
//案例: 演示泛型的上下界之 上界. object ClassDemo04 { //1. 定義一個Person類 class Person //2. 定義一個Student類,繼承Person類 class Student extends Person //3. 定義一個demo泛型方法,該方法接收一個Array引數, //限定demo方法的Array元素型別只能是Person或者Person的子類 def demo[T <: Person](arr: Array[T]) = println(arr) def main(args: Array[String]): Unit = { //4. 測試呼叫demo,傳入不同元素型別的Array //demo(Array(1, 2, 3)) //這個會報錯, 因為只能傳入Person或者它的子型別. demo(Array(new Person())) demo(Array(new Student())) } }
使用T >: 資料型別
表示給型別新增一個下界,表示泛型引數必須是從該型別本身或該型別的父類別型.
格式
[T >: 型別]
注意:
例如: [T >: Person]的意思是, 泛型T的資料型別必須是Person型別或者Person的父類別型如果泛型既有上界、又有下界。下界寫在前面,上界寫在後面. 即: [T >: 型別1 <: 型別2]
需求
參考程式碼
//案例: 演示泛型的上下界之 下界. //如果你在設定泛型的時候, 涉及到既有上界, 又有下界, 一定是: 下界在前, 上界在後. object ClassDemo05 { //1. 定義一個Person類 class Person //2. 定義一個Policeman類,繼承Person類 class Policeman extends Person //3. 定義一個Superman類,繼承Policeman類 class Superman extends Policeman //4. 定義一個demo泛型方法,該方法接收一個Array引數, //限定demo方法的Array元素型別只能是Person、Policeman // 下界 上界 def demo[T >: Policeman <: Policeman](arr: Array[T]) = println(arr) def main(args: Array[String]): Unit = { //5. 測試呼叫demo,傳入不同元素型別的Array //demo(Array(new Person)) demo(Array(new Policeman)) //demo(Array(new Superman)) //會報錯, 因為只能傳入: Policeman類獲取它的父類別型, 而Superman是Policeman的子型別, 所以不行. } }
在Spark的原始碼中大量使用到了協變、逆變、非變,學習該知識點對閱讀spark原始碼很有幫助。
任何關係
.父子類
關係.子父類別
關係.如下圖:
語法格式
class Pair[T]{}
非變的
語法格式
class Pair[+T]
語法格式
class Pair[-T]
需求
參考程式碼
//案例: 演示非變, 協變, 逆變. object ClassDemo06 { //1. 定義一個Super類、以及一個Sub類繼承自Super類 class Super //父類別 class Sub extends Super //子類 //2. 使用協變、逆變、非變分別定義三個泛型類 class Temp1[T] //非變 class Temp2[+T] //協變 class Temp3[-T] //逆變. def main(args: Array[String]): Unit = { //3. 分別建立泛型類來演示協變、逆變、非變 //演示非變. val t1:Temp1[Sub] = new Temp1[Sub] //val t2:Temp1[Super] = t1 //編譯報錯, 因為非變是: Super和Sub有父子類關係, 但是Temp1[Super] 和 Temp1[Sub]之間沒有關係. //演示協變 val t3:Temp2[Sub] = new Temp2[Sub] val t4:Temp2[Super] = t3 //不報錯, 因為協變是: Super和Sub有父子類關係, 所以Temp2[Super] 和 Temp2[Sub]之間也有父子關係. //Temp2[Super]是父類別型, Temp2[Sub]是子型別. //演示逆變 val t5:Temp3[Super] = new Temp3[Super] val t6:Temp3[Sub] = t5 //不報錯, 因為逆變是: Super和Sub有父子類關係, 所以Temp3[Super] 和 Temp3[Sub]之間也有子父關係. //Temp3[Super]是子型別, Temp3[Sub]是父類別型. } }
到此這篇關於Scala泛型(泛型方法,泛型類,泛型特質,上下界,協變、逆變、非變)的文章就介紹到這了,更多相關Scala泛型內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45