zok81
zok81

Reputation: 33

Value of type 'Protocol' has no member 'Function'

In the code below, when I try to access genericVar.someFunc() I get the error

"Value of type 'MyProtocol?' has no member 'someFunc'".

Being a generic variable, when I initialize the MyOtherStruct object, I will have to pass a concrete implementation of a MyProtocol conforming object, so why would I be getting this error?

public protocol MyProtocol {

    associatedtype T
    func someFunc() -> T
}

public struct myStruct: MyProtocol {
    public typealias T = Int16

    public func someFunc() -> Int16 {
        let myVar: Int16 = 7
        return myVar
    }
}

public struct myOtherStruct<MyProtocol> {

    var genericVar: MyProtocol?

    public init(localVal: MyProtocol?) {
        self.genericVar = localVal
        if genericVar != nil {
            var my = genericVar.someFunc()
        }
    }
}

Upvotes: 3

Views: 1619

Answers (1)

David Pasztor
David Pasztor

Reputation: 54706

Your generic type declaration is wrong. MyProtocol in the brackets is the name of the generic type parameter rather than the actual protocol. You need to declare another name for the generic type parameter and constrain it to MyProtocol like this: struct MyOtherStruct<T:MyProtocol>. Here T will be the generic type parameter of the struct and the :MyProtocol syntax enforces that T conform to myProtocol.

public struct MyOtherStruct<T:MyProtocol> {
    var genericVar: T?

    public init(localVal: T?) {
        self.genericVar = localVal
        if let genericVar = genericVar {
            let my = genericVar.someFunc()
        }
    }
}

Some other things to consider: you should conform to the Swift naming convention, which is UpperCamelCase for types and when you want to access a property/method on an Optional value, instead of doing a nil comparison like if genericVar != nil you should use optional binding using if let.

Upvotes: 3

Related Questions