Why I can't use let in protocol in Swift?

Massimo Polimeni picture Massimo Polimeni · Dec 20, 2015 · Viewed 20.5k times · Source

I have a doubt about protocols in Swift about the use of var and the keywords { get set }.

From Apple documentation:

If a protocol requires a property to be gettable and settable, that property requirement cannot be fulfilled by a constant stored property or a read-only computed property. If the protocol only requires a property to be gettable, the requirement can be satisfied by any kind of property, and it is valid for the property to be also settable if this is useful for your own code.

Property requirements are always declared as variable properties, prefixed with the var keyword. Gettable and settable properties are indicated by writing { get set } after their type declaration, and gettable properties are indicated by writing { get }.

I can't understand why I can't use let. A var in a protocol with only get isn't just a let?

Something like this:

protocol someProtocol 
{
   var someProperty: String { get }
}

it would not be just:

protocol someProtocol 
{
   let someProperty: String
}

I'm missing something?

Answer

luk2302 picture luk2302 · Dec 20, 2015

"A var in a protocol with only get isn't just a let?" No. A let indicates a constant. But that is not the case here. Consider the following:

protocol SomeProtocol {
    var someProperty: String { get }
}

class SomeClass : SomeProtocol {

    var someProperty: String = ""

    func cla () {
        someProperty = "asd"
    }
}

let someInstance = SomeClass()

print(someInstance.someProperty) // outputs ""
someInstance.cla()
print(someInstance.someProperty) // outputs "asd"

The protocol specifies what the conforming class shows to the outside - some property of type String named someProperty which you can at least get.

If the protocol specifies { get } your class can choose to conform via let someProperty: String = "" but it can similarly choose to conform via the above code. If on the other hand the protocol specifies { get set } you cannot use let in the implementation but have to make it set-able as well.

A protocol simply cannot define that a value has to be constant - neither should it, that is an implementation detail that has to be taken care (or decided about) by the class / struct that implements it.