scala的協變和逆變分析

2021-06-21 21:37:32 字數 840 閱讀 1639

首先引用朋友的文章

對於函式返回值引用宣告為協變的物件定義

由於物件宣告是正向擴充套件的,實際處理型別總比宣告型別範圍精確,則返回物件必然被宣告物件相容

trait cat[+t] 

val child = new cat[string]

val parent: cat[any] = child

val voice:any = parent.meow

我們可以看到,宣告的cat[any]可以指向cat[string],則voice必然可以引用到meow

對於函式返回值引用宣告為逆變的物件定義

由於物件宣告是反向收縮的,實際處理型別總比宣告型別範圍粗略,則返回物件必然會成為宣告物件的兄弟物件,則不能處理。

trait cat[-t] 

val child = new cat[any]

val parent: cat[string] = child

val voice:string = parent.meow // error !!!

可以看到,宣告的cat[string]可以指向cat[any],但是因為any的範圍比string的範圍粗略,則返回物件成了string的兄弟物件。

簡單說,-t無法控制t的旁枝轉型,t可以t1,t無法相容t'

引數為逆變:引數可以處理比宣告型別更精確的值。逆變則可以使的精確型別指向粗略型別

引數為逆變,意味著:我能處理比宣告型別更精確的型別,只要更精確的型別是他的宣告的型別的子類

返回值為協變,意味著:他能處理比我宣告的型別更精確的型別,只要我的型別是他型別的子類。

協變和逆變

協變和逆變都是術語,前者指能夠使用比原始指定的派生型別的派生程度更大的型別,後者指能夠使用比原始指定的派生型別的派生程度更小的型別。using system using system.collections.generic using system.text class derived base s...

協變和逆變

二 真正的協變和逆變 概念 1 以前的泛型系統 或者說沒有in out關鍵字時 是不能 變 的,無論是 逆 還是 順 協 2 當前僅支援介面和委託的逆變與協變 不支援類和方法。但陣列也有協變性。3 值型別不參與逆變與協變。協變 foo foo public class testoutwhere t ...

協變和逆變

假設有這樣乙個類 class person icloneable 但是由於我們知道是返回乙個person類的例項,所以返回型別 object 寫在這裡總會覺得很彆扭,我們希望寫成 class person icloneable 顯然,這是錯的 雖然這是錯的,但這就是返回型別的協變性,只是非泛型介面和...