2015-11-17 20 views
3

是否有可能將泛型類型約束爲在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() 
} 

當然,上面的代碼不能被編譯和失敗:

使用「遞增的」作爲具體類型符合協議 「AnyObject」不支持

是否有可能寫Weak包裝內,以便它可以接受和弱引用存儲協議?


雖然在Using as a concrete type conforming to protocol AnyObject is not supported是質疑與哈希表交易和我需要列出了允許重複項解決我的問題的根本原因是一樣的。

+1

的可能的複製(http://stackoverflow.com/questions/32807948/using-as-a-concrete-type-conforming-to-協議anyobject不支持) –

+0

@BartłomiejSemańczyk我不認爲這是重複的,但在該問答的幫助下,我設法得到了更好的解決方案,我的問題,我張貼它作爲答案。但是,如果任何人有更好的建議/解決方案,我都聽過。 –

+0

爲什麼'AnyObject'不夠?唯一的其他選擇是結構,我不確定引用應該如何與結構一起工作? – Sulthan

回答

1

以下answer指出我正確的方向,我能夠想出以下解決方案實施協議參考的弱列表,允許重複項和nil(便利)條目。 [不支持使用作爲具體類型符合協議AnyObject]

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() 
}