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

IosSwiftProtocolsGetter SetterSwift Protocols

Ios Problem Overview


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?

Ios Solutions


Solution 1 - Ios

"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.

Solution 2 - Ios

The difference is between

protocol MyProtocol {
    let someProperty: String
}

which makes no sense — a protocol isn't supposed to dictate how someProperty is defined/stored, only that it's available as a property. It could be either a computed or stored property, but that's for the implementer to decide, not the protocol itself.

and

protocol MyProtocol {
    var someProperty: String { get }  // abstract interface
}

struct MyStruct: MyProtocol {
    let someProperty: String  // concrete implementation: stored property
}

struct OtherStruct: MyProtocol {
    let i: Int
    var someProperty: String { return "\(i)" }  // concrete implementation: computed property
}

which is perfectly allowed!

Solution 3 - Ios

I think a protocol can require that a structure has something, but it can't restrict functionality of struct or object. That shouldn't prevent you from doing what you'd probably like to do in code, for example using a var in the protocol and a let for the implementation is acceptable.

protocol MyProtocol {
    var trythis: Int { get }
}

struct MyStructure: MyProtocol {
    let trythis: Int
}

Solution 4 - Ios

A property declared with let is considered read-only under the hood. For this reason, a protocol can require that a property be a constant by setting it read-only. This deduction can be verified using some of the Objc runtime functions property_getAttributes.

protocol SomeProtocol {
    var someTypeProperty: Int { get }
}

struct Foo: SomeProtocol {
    let someTypeProperty: Int
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMassimo PolimeniView Question on Stackoverflow
Solution 1 - Iosluk2302View Answer on Stackoverflow
Solution 2 - IosjtbandesView Answer on Stackoverflow
Solution 3 - IosScottyBladesView Answer on Stackoverflow
Solution 4 - IosZiad TamimView Answer on Stackoverflow