I write a custom storage, that should supports only objects that conform some protocol:
protocol MyBaseProtocol {
func baseMethod()
}
class Stor <ElementType : MyBaseProtocol> {
var storage = [ElementType]()
func addElement(_ element: ElementType) {
storage.append(element)
}
}
Next I've created a child protocol and want to store only objects what conform the child protocol:
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())
I've got an error:
Value of protocol type 'MyProtocol' cannot conform to 'MyBaseProtocol'; only struct/enum/class types can conform to protocols
How I can create an instance of Stor that can store only objects that conform MyBaseProtocol?
You are running into the issue of protocols not conforming to themselves. You can resolve this by creating a concrete type conforming to MyProtocol
and converting all your conforming types to that before storing them in your 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)