首页 > 解决方案 > 用另一个泛型扩展一个泛型类型

问题描述

是否可以使用包含另一个泛型的 where 子句要求来扩展泛型类型?

基本上是这样的:

class WeakStore<Element: AnyObject> {
    weak var value: Element?

    init(_ value: Element) {
        self.value = value
    }
}

extension Dictionary where Value == WeakStore<Element> {
    public subscript(weak key: Key) -> Element? {
        get {
            self[key].value
        }

        set {
            if let exists = self[key] {
                exists.value = newValue
            } else {
                self[key] = WeakStore(newValue)
            }
        }
    }
}

为了澄清,这不会建立并提供许多错误。此外,虽然提示这个特定问题的原因是试图让弱字典正常工作,但请继续关注如何使用另一个泛型(如果可能的话)扩展泛型类型,因为它适用于远远超出此特定用例的内容。

标签: swiftgenerics

解决方案


我不相信它可以做到这一点。(我实际上不确定为什么;感觉它只是语法和编译器功能,但可能还有更深层次的东西我还没有发现。)

但是,我可以通过添加协议来完成:

public protocol WeakStoreType: AnyObject {
    associatedtype Element: AnyObject
    var value: Element? { get set }
    init(_ value: Element)
}

extension WeakStore: WeakStoreType {}

这只是包装WeakStore到一个协议中,然后使 WeakStore 符合该协议,将泛型参数替换为关联类型。

您的 Dictionary 扩展程序中有一些错误,但可以按如下方式修复:

public extension Dictionary where Value: WeakStoreType {
    subscript(weak key: Key) -> Value.Element? {
        get {
            self[key]?.value
        }

        set {
            if let exists = self[key] {
                exists.value = newValue
            } else if let newValue = newValue {
                self[key] = Value(newValue)
            } else {
                self[key] = nil
            }
        }
    }
}

推荐阅读