在 swift 的具有类型约束的泛型中使用协议

Use protocol in swift's generic with type constraint

我写了一个自定义存储,应该只支持符合某些协议的对象:

protocol MyBaseProtocol {
    func baseMethod()
}
class Stor <ElementType : MyBaseProtocol>  {
    var storage = [ElementType]()
    
    func addElement(_ element: ElementType) {
        storage.append(element)
    }
}

接下来我创建了一个子协议并希望只存储符合子协议的对象:

protocol MyProtocol : MyBaseProtocol {
    func method()
}
var otherStorage = Stor<MyProtocol>() //compilation error
class C1 : MyProtocol {
    func method() {
    }
    func baseMethod() {
    }
}
class S1 : MyProtocol {
    func method() {
    }
    func baseMethod() {
    }
}
otherStorage.addElement(C1())
otherStorage.addElement(S1())

我有一个错误:

Value of protocol type 'MyProtocol' cannot conform to 'MyBaseProtocol'; only struct/enum/class types can conform to protocols

如何创建一个 Stor 实例,它只能存储符合 MyBaseProtocol 的对象?

您 运行 关注 的问题。您可以通过创建符合 MyProtocol 的具体类型并将所有符合类型转换为该类型,然后再将它们存储在 Store.

中来解决此问题
class AnyMyProtocol: MyProtocol {
    private let _baseMethod: () -> ()
    private let _method: () -> ()

    init(base: MyProtocol) {
        _baseMethod = base.baseMethod
        _method = base.method
    }

    func baseMethod() {
        _baseMethod()
    }

    func method() {
        _method()
    }
}

extension MyProtocol {
    var erased: AnyMyProtocol {
        AnyMyProtocol(base: self)
    }
}

var otherStorage = Store<AnyMyProtocol>()

class C1 : MyProtocol {
    func method() {}
    func baseMethod() {}
}

struct S1 : MyProtocol {
    func method() {}
    func baseMethod() {}
}

enum MyEnum: MyProtocol {
    case some

    func method() {}
    func baseMethod() {}
}

otherStorage.addElement(C1().erased)
otherStorage.addElement(S1().erased)
otherStorage.addElement(MyEnum.some.erased)