I have the following function in an extension on a class (in my case XCUIElement
but I think this setup could apply to a lot of contexts quite easily) which has a closure with a parameter of Self
. It's useful to do this so the type of the parameter is automatically inferred, for example if you decide to run this method on a subclass of XCUIElement
, such as XCUIApplication
.
The details of my methods aren't really relevant here so I made a simplified example which I verified in a playground.
class MyClass {}
extension MyClass {
func myMethod(_ closure: (Self) -> Void) {
closure(self) // <-- compiler error
}
}
The compiler error says:
Cannot convert value of type 'XCUIElement' to expected argument type 'Self'
But if I put the same method inside an extension of some protocol I make, and then conform MyClass
to that protocol, it works fine and the type inside the closure is inferred properly.
protocol MyProtocol {}
extension MyClass: MyProtocol {}
extension MyProtocol {
func foo2(_ closure: (Self) -> Bool) {
closure(self)
}
}
Is this an expected behaviour of Swift? If so, why is it different for a class versus a protocol in this context? I know there are differences between protocols and classes but this seems fairly arbitrary to me.
I am using Xcode 13.4.1, macOS 12.4 (21F79) (Apple M1 Max), Swift 5.6.