Both a struct and a class conforms to a protocol. I use 2 protocol extensions with where
conditions to add an implementation of the var property for both class and struct.
I'm quite surprised to see a compile error for classes only.
Why does this happen for classes and not for structs?
protocol MyProtocol {
var property:String { get }
}
extension MyProtocol where Self == MyStruct {
var property: String { return "" }
}
extension MyProtocol where Self == MyClass {
var property: String { return "" }
}
struct MyStruct : MyProtocol {}
class MyClass : MyProtocol {} //Type 'MyClass' does not conform to protocol 'MyProtocol'
It does not compile because your
extension MyProtocol where Self == MyClass
provides a default method only for MyClass
itself, but not for possible subclasses. Changing the constraint to
extension MyProtocol where Self: MyClass
makes the code compile. Alternatively prevent the creation of subclasses with
final class MyClass : MyProtocol {}
This is not a problem for MyStruct
because struct types cannot be inherited from in Swift.
Classes can inherit from other classes.
So some class X
may inherit from MyClass
.
But your extension provides implementation of MyProtocol
properties of if the class is MyClass
and not it's descendant. So any class that inherits from MyClass
won't have any properties of MyProtocol
implemented. And that is the problem.
If you declare MyClass
final
your code would be valid:
final class MyClass : MyProtocol {}
If you extend conditional extension to any MyClass
descendants your code would be valid:
extension MyProtocol where Self: MyClass {
var property: String { return "" }
}
But right now all those potential subclasses lack implementation for MyProtocol
and it is not allowed.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.