Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift: Providing a default protocol implementation in a protocol extension

I'm trying to play around a bit with Swift, protocols and protocol extensions. Specifically I'm trying to provide a default implementation of a protocol in a protocol extension. This is my code:

protocol Proto : class {
    func someMethod() -> String
}

extension Proto {
    static func create() -> Self {
        return ProtoDefaultImpl() as! Self
    }
}

class ProtoDefaultImpl : Proto {
    func someMethod() -> String {
        return "doing something"
    }
}

let instance = Proto.create()
let output = instance.someMethod()

print(output)

The compiler complains on the line where I call Proto.create(), with the following error: error: static member 'create' cannot be used on instance of type 'Proto.Protocol'.

Have I missed something here? Is there any way you can achieve this?

Thanks.

like image 552
vrutberg Avatar asked Dec 25 '22 09:12

vrutberg


1 Answers

You can't call the method on the protocol itself, you have to call it on a type that implements the protocol. This doesn't change because there is a default implementation of the protocol in an extension. Change your type from Proto to ProtoDefaultImpl and it will work as you expect.

protocol Proto : class {
    func someMethod() -> String
}

extension Proto {
    static func create() -> Self {
        return ProtoDefaultImpl() as! Self
    }
}

class ProtoDefaultImpl : Proto {
    func someMethod() -> String {
        return "doing something"
    }
}

let instance = ProtoDefaultImpl.create()
let output = instance.someMethod()

print(output)

This outputs: doing something

like image 184
Mr Beardsley Avatar answered Jan 14 '23 08:01

Mr Beardsley