簡體   English   中英

Swift:數組屬性,其元素同時符合一個類和多個協議

[英]Swift: Array property with elements conforming to a class and multiple protocols simultaneously

在Objective-C中,有一種方法可以聲明一個符合類和一組協議的變量,如下所示:

BaseClass<Protocol1, Protocol2> *variable = ...

在Swift中,我想聲明一個數組(實際上是一個類的屬性),該數組具有此模式定義的類型的元素。

這個問題中,有一個解決方案,通過使類通用並相應地限制類型來描述獨立屬性的類型。 為了實例化這樣的類,有必要指定確切的類型。 對於獨立屬性這不是問題,但是在數組中應該可以存儲具有不同確切類型的元素。

有沒有一種方法可以在Swift中表達呢?

感謝@SebastianDressler@ Mike-S,我發現沒有一種簡單的方法可以在Swift中表達它。

但是,您可以做的是像這樣限制要添加到數組中的項目的類型:

func addItem<T where T: BaseClass, T: Protocol1, T: Protocol2>(item: T) {
    self.array.append(item)
}

當將其類型定義為協議的基類之一時,無法從數組中投射項目,因為編譯器看不到這些類型之間的任何關系。

為了能夠轉換為基類或協議之一,必須將類型聲明為AnyObject

var array: [AnyObject] = []

並且僅在使用@objc注釋協議時才強制轉換為協議(請參閱https://stackoverflow.com/a/24318145/670119 )。

在這種情況下,您只想存儲符合協議的對象,則可以使另一個協議繼承其他協議,例如

protocol A { }
protocol B { }
protocol C : A, B { }

現在您可以創建相應的數組

var objects : [ C ]

您可以存儲任何對象,只要它符合C協議,並因此也符合AB

class Foo : X { }
class Bar : X { }

objects.append(Foo()) // [ Foo ]
objects.append(Bar()) // [ Foo, Bar ]

背后的技術是協議繼承

更新 IMO,這對於Swift Array是不可行的。 因為,您可以存儲從基類繼承的類型,也可以存儲不滿足約束的AnyObject 但是您可以創建一個包裝器,以檢查您嘗試添加到數組中的對象,如果不符合約束條件則拒絕該對象。

我剛剛遇到了我的這個老問題,因為自從接受部分答案以來Swift語言就發展了,所以我決定發布另一個答案,該答案實際上解決了我最初提出的問題。

從版本4開始,Swift支持使用&符號構成協議,該符號也可以由一種類類型組成。

class BaseClass {}
protocol Protocol1 {}
protocol Protocol2 {}

class ConformingClass1: BaseClass, Protocol1, Protocol2 {}
class ConformingClass2: BaseClass, Protocol1, Protocol2 {}

// It works for a variable holding a single object.
let object: BaseClass & Protocol1 & Protocol2 = ConformingClass1()

// And it also works for a variable holding an array of objects.
let array: [BaseClass & Protocol1 & Protocol2] = [ConformingClass1(), ConformingClass2()]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM