Home > Software engineering >  How can I reference a protocol instance variable from a protocol method?
How can I reference a protocol instance variable from a protocol method?

Time:12-19

I have created a Swift package Example. Inside Example.swift I have the following:

import Foundation

protocol Foo {
    var bar: String { get }
}

extension Foo {
    static func main() {
        print(bar)
    }
}

@main
struct Example: Foo {
    let bar = "Hello World"
}

I get the error instance member 'bar' cannot be used on type 'Self'. How can I access a protocol member from within a protocol method ?

CodePudding user response:

This has nothing to do with whether you are in a protocol method or not. You need an instance of a type that conforms to Foo, e.g. an instance of Example, in order to access bar. There is no such instance in the static main method. In fact, you do not create any such instances in your entire program.

You can create an Example and access foo like this:

extension Foo {
    static func main() {
        print(Example().bar)
    }
}

But that kind of loses the point of having a protocol in the first place. I'm guessing you want whatever type T that conforms to Foo to have a main method that prints the bar that T declares, rather than always Example.bar.

In that case, you can require an additional initialiser in the protocol, giving you a way to create a new instance of whatever type it is that conforms to the protocol.

protocol Foo {
    var bar: String { get }
    
    init()
}

extension Foo {
    static func main() {
        // create an instance of myself, and access bar
        print(Self().bar)
    }
}

Instantiating the class is done by the package stuff, as far as I can tell.

This is not true. The @main annotation just calls Example.main(). An instance is not, and does no need to be, created. Because main is static after all.

  • Related