Denis
Denis

Reputation: 199

Swift Protocols: Difference between { get } and { get set } with concrete examples?

I'm pretty new to Swift, and although I've read Apple's documentation and many topics and threads about this, I still can't understand what's the difference between { get } and { get set }. I mean, I'm looking for an explanation with a concrete example.

Like, for example:

protocol PersonProtocol {
    var firstName: String { get }
    var lastName: String { get set }
}

What would be the actual difference between these two properties? I tried to play with these properties in a playground:

struct Person: PersonProtocol {
    var firstName: String
    var lastName: String
}

var p = Person(firstName: "John", lastName: "Lennon")
print(p.firstName) // John
print(p.lastName) // Lennon
p.firstName = "Paul"
p.lastName = "McCartney"
print(p.firstName) // Paul
print(p.lastName) // McCartney

Did not help... Thanks for your help.

Upvotes: 5

Views: 10711

Answers (2)

user28434'mstep
user28434'mstep

Reputation: 6600

protocol — is a requirement of some minimal interface of the type implementing it.

  • var name: Type { get } requires type to have property with at least a getter (accessible from outside of the type, not private), i.e. outside code should be able to read value of the property. In the implementing type it could be let name: Type, var name: Type, private(set) var name: Type, fileprivate(set) var name: Type, etc.

  • var name: Type { get set } requires type to have property with both accessible getter and setter, i.e. outside code should be able to read and write to the property. Here only var name: Type would be allowed.

If protocol requires for getter but you also provide a setter — it's not against protocol requirements. But if protocol requires for both getter and setter — you must provide both, and not having any of them won't be valid implementation.


Your Person class defined both properties as var(with accessible getter and setter) therefore you can change them both. But PersonProtocol haven't required ability to set firstName.

And as @JoakimDanielson shows, if you will use just interface required by protocol you won't be to change the firstName value.

Upvotes: 10

Joakim Danielson
Joakim Danielson

Reputation: 52088

You are creating a variable of type Person and there are no restrictions on that struct. If you instead create a variable of type PersonProtocol then firstName will be read only

var p1: PersonProtocol = Person(firstName: "John", lastName: "Lennon")
print(p1.firstName) // John
print(p1.lastName) // Lennon
p1.firstName = "Paul" <== error: cannot assign to property: 'firstName' is a get-only property

Upvotes: 16

Related Questions