簡體   English   中英

Swift中任何協議的通用約束

[英]Generic constraint for any protocol in Swift

是否可以在Swift中約束泛型類型以接受協議?

我已經實現了包裝器以獲得弱對象列表,我需要將其擴展到協議。

protocol Incrementable: class {
    func inc()
}

class Counter: Incrementable {
    var n: Int = 0

    func inc() {
        n += 1
    }
}

struct Weak<T: AnyObject> {
    weak var value : T?
    init (value: T?)
    {
        self.value = value
    }
}

var cnt: Counter? = Counter()

let counters : [Weak<Counter>] = [Weak(value: cnt), Weak(value: Counter())]

for counter in counters
{
    counter.value?.inc()
}

現在,如果我想存儲實現Incrementable任何對象,我必須使用AnyObject ,這不是非常類型安全,還包括as? 鑄件

let counters : [Weak<AnyObject>] = [Weak(value: cnt), Weak(value: Counter())]

for counter in counters
{
    (counter.value as? Incrementable)?.inc()
}

我想要的代碼就是

let counters: [Weak<Incrementable>] = [Weak(value: cnt), Weak(value: Counter())]

for counter in counters
{
    counter.value?.inc()
}

當然,以上代碼無法編譯並失敗:

不支持使用'Incrementable'作為符合協議'AnyObject'的具體類型

是否可以編寫Weak包裝器,以便它可以接受和存儲對協議的弱引用?


雖然我的問題的根本原因與使用符合協議的具體類型相同AnyObject不支持該問題處理哈希表,我需要具有允許重復條目的列表的解決方案。

以下回答指出了我正確的方向,我能夠提出以下解決方案來實現允許重復和nil (便利)條目的協議引用的弱列表。

struct Weak<T>
{
    weak var value: AnyObject?
    init (value: T?)
    {
        if value != nil
        {
            guard value is AnyObject else { fatalError("Object (\(value)) should be subclass of AnyObject") }
            self.value = value as? AnyObject
        }
    }
}

class WeakList<T>: SequenceType
{
    var items : [Weak<T>] = []

    func add(item: T?)
    {
        items.append(Weak(value: item))
    }

    func generate() -> AnyGenerator<T>
    {
        var nextIndex = items.count - 1

        return anyGenerator
        {
            while nextIndex >= 0
            {
                let item = self.items[nextIndex--]
                if item.value != nil
                {
                   return item.value as? T
                }
            }
            return nil
        }
    }
}

let incrementables = WeakList<Incrementable>()

incrementables.add(Counter())
incrementables.add(cnt)
incrementables.add(nil)
incrementables.add(Counter())
incrementables.add(cnt)

for counter in incrementables
{
    counter.inc()
}

暫無
暫無

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

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