Search code examples
swiftswift2xcode7-beta5

Are inout variables of protocol type prohibited?


The following code:

protocol SomeProtocol {}
class SomeClass: SomeProtocol {}

private func doSomethingWith(inout someVar: SomeProtocol) {}

private var someGlobalVar = SomeClass() // inferring SomeClass's type

doSomethingWith(&someGlobalVar)

produces the following error:

Cannot invoke 'doSomethingWith' with an argument list of type '(inout SomeClass)'

Changing the penultimate line to private var someGlobalVar: SomeProtocol = SomeClass() resolves the error.

Subj.


Solution

  • When you assign a SomeClass instance to a variable while declaring, the variable type is inferred to be SomeClass. The same as writing

    private var someGlobalVar: SomeClass = SomeClass()
    

    However, when passing to an inout parameter, the function can assign another instance to that variable, e.g.

    private func doSomethingWith(inout someVar: SomeProtocol) {
        someVar = OtherClass()
    }
    

    Now you have a type mismatch. The error you are seeing is Swift preventing you getting a similar problem.

    In other words: if you are passing a variable to a function and you know that the function can assign any instance adopting SomeProtocol to that variable, you have to use a variable that can actually hold any instance adopting SomeProtocol:

    private var someGlobalVar: SomeProtocol