閱讀350 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Coursera Scala 4-3:子類型和泛型


Coursera Scala 4-3:子類型和泛型

Type Bounds

def assertAllPos[S <: IntSet](r: S): S = ...
  • S <: T 表示S是T的子類
  • S >: T表示S是T的父類

也可以這麼用:

[S >: NonEmpty <: IntSet]

協變covariant

這個的意思是:
如果List是convariant的,S<:T (S是T的子類)成立,那麼List[S]<:List[T]也成立

covariant帶來的問題:

NonEmpty[] a=new NonEmpty[]{new NonEmpty(1,Empty,Empty)}
IntSet[] b = a
b[0]=Empty
NonEmpty s=a[0]

Empty不是NonEmpty 若執行肯定會錯

這裏NonEmpty是Inset的子類 java中Array是covariant的
所以 第二行成立 但Empty不是NonEmpty
java中的解決方法是在創建Array的時候就放入一個表明最初創建類型的Tag
因為Empty不是NonEmpty類型的 所以 b[0]=Empty這句話就會報錯(所以是個運行時的錯誤)

scala中的Array就不是corvariant的:
var x=ArrayAny
var y=ArrayInt
x=y //這裏報錯 type mismatch; found : Array[Int] required: Array[Any]

裏氏替換原則:
Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.
if S<:T then q(x:T)==true ==> q(y:S)==true
如果下A<:B 那麼對B能進行的操作 對A也可以進行
或者說對於q(x) x是B類型的能工作 那麼q(y) y是A類型的也能工作如果A<:B

也就是 父類型能做的 子類型也要能做
要達到這個 父類方法的參數類型要比子類的"窄"(父類的參數類型要是子類參數類型的子類) 但父類方法的返回值類型應該要比子類的"寬"

逆變

Reference

scala泛型


最後更新:2017-04-03 05:39:17

  上一篇:go php-fpm.conf配置說明(重點要修改和優化的地方)
  下一篇:go Coursera Scala 2-5,6:類