I'm following a tutorial on the protocol oriented programming paradigm in which I'm confused by something I thought was rather simple which is read only properties of protocols or getters and setters. My understanding is that a read only property is signified by using the keyword 'get' when declaring a variable within a protocol. I was excited so I quickly coded created a playground to see if my thinking was accurate however it appears that I can still change the property which I thought was read only. What am I doing wrong to make it a true read only property to where I can't set it?
protocol FullName {
var firstName: String {get set}
var lastName: String {get set}
var readOnlyProperty: String {get}
}
struct OuttaBeerOuttaHere: FullName {
var firstName: String
var lastName: String
var readOnlyProperty: String = "Jack! Jack!...Line from Titanic"
}
var leonardoDicaprio = OuttaBeerOuttaHere.init(firstName: "Leonardo", lastName: "Dicaprio", readOnlyProperty: "WTF")
print(leonardoDicaprio.readOnlyProperty) //prints "WTF"
leonardoDicaprio.readOnlyProperty = "what now"
print(leonardoDicaprio.readOnlyProperty) //prints "what now"
What am I doing wrong to make it a true read only property to where I can't set it?
There is a difference between a protocol (a set of rules) and the type (i.e. your struct) that adopts the protocol.
Your protocol rule says that readOnlyProperty
should be readable.
Your struct obeys by making it readable, and also makes it writable. That is not illegal, so all is well — and readOnlyProperty
in your struct is read-write.
What would have been illegal would be the inverse, i.e. for the protocol to declare a property read-write but the adopter to declare it read-only. That situation didn't arise in your example, but if it had, the compiler would have stopped you.
Your protocol doesn't declare readOnlyProperty
as a read-only property. It only requires that implementations of that protocol have at least gettable readOnlyProperty
property. To allow mutations of that property or not is up to implementation itself.
From Docs
Here’s an example of a protocol with a single instance property requirement:
protocol FullyNamed {
var fullName: String { get }
}
The FullyNamed protocol requires a conforming type to provide a
fully-qualified name. The protocol doesn’t specify anything else about
the nature of the conforming type—it only specifies that the type must
be able to provide a full name for itself. The protocol states that
any FullyNamed type must have a gettable instance property called
fullName, which is of type String
it's a requirement from the protocol not a define