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()
}
当然,上面的代码无法编译并失败:
Using 'Incrementable' as concrete type conforming to protocol
'AnyObject' is not supported
是否可以编写 Weak
包装器以便它可以接受和存储对协议的弱引用?
虽然我的问题的根本原因与 中的相同,但该问题涉及哈希表,我需要使用允许重复条目的列表的解决方案。
以下 为我指明了正确的方向,我能够想出以下解决方案来实现允许重复和 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()
}
是否可以约束泛型类型以接受 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()
}
当然,上面的代码无法编译并失败:
Using 'Incrementable' as concrete type conforming to protocol 'AnyObject' is not supported
是否可以编写 Weak
包装器以便它可以接受和存储对协议的弱引用?
虽然我的问题的根本原因与
以下 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()
}