sak sak - 1 month ago 6
Swift Question

Protocol requirement cannot be satisfied by a non-final class because it uses 'Self' in a non-parameter, non-result type

I want to implement a protocol with a class method that takes an array of the implementing class as a parameter. For instance something like this:

protocol MyProtocol {
static func foo(verticies: [Self]) -> Int
}

class MyClass : MyProtocol {
class func foo(verticies: [MyClass]) -> Int {
return 42
}
}


When I attempt this, I get the following error:


Protocol 'MyProtocol' requirement 'foo()' cannot be satisfied by a non-final 'MyClass' class because it uses 'Self' in a non-parameter, non-result type


But this works perfectly if I use an object of type MyClass rather than an array:

protocol MyProtocol {
static func foo(verticies: Self) -> Int
}

class MyClass : MyProtocol {
class func foo(verticies: MyClass) -> Int {
return 42
}
}


Why doesn't this work for an array type, and is there a correct way to do this?

Answer

The problem has to do with the indeterminate nature of what would happen if MyClass had a subclass (because generics, such as Array, are not classes and don't magically do polymorphism). Just do what the error message says, and all will be well:

protocol MyProtocol {
    static func foo(verticies:[Self]) -> Int
}
final class MyClass : MyProtocol {
    class func foo(verticies:[MyClass]) -> Int {
        return 1
    }
}