0
protocol UserType {
    var name: String { get }
    var age: Int { get set }


struct Person: UserType { 
    var name: String //<- why is this okay?
    var age: Int //<- why is this okay? dont we need a getter setter
}

let somePerson = Person(name: "Billy", age: 22)

Why in the above examples, we dont use get constructs or set constructs for age and a get construct for name? Is it because in the protocol when the property is said to "{ get set }" that essentially means it has to be able to be read and has to be able to be changed, which can be done through a declaration in the syntax of a stored property?

Thanks!

rmaddy
  • 314,917
  • 42
  • 532
  • 579
JonEF
  • 1
  • 1
  • Because stored properties are instance variables which are given compiler-synthesized get and set functions – Alexander Feb 09 '18 at 18:35
  • Related: [How can you conform protocol variables' set & get?](https://stackoverflow.com/questions/40820913/how-can-you-conform-protocol-variables-set-get) – In particular: *"The protocol doesn’t specify whether the property should be a stored property or a computed property—it only specifies the required property name and type."* – Martin R Feb 09 '18 at 18:54

2 Answers2

2
protocol UserType {
    var name: String { get }
    var age: Int { get set }
}

The important thing to understand is that { get } and { get set } are merely notations. They have nothing to do with "getter and setter". They are merely ways of describing to the compiler what the protocol's requirements are. (You could argue that the notation is confusing or misleading, but it's what we've got, so we have to live with it.)

So, basically, all this says is:

  • An adopter must declare a name String instance property.

  • An adopter must also declare an age Int instance property and that property must be writable.

That's all it means. Well, you have satisfied those requirements in your adopter (Person). Your code is legal. The end.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • while functionally correct, the get and set annotations have _everything_ to do with a getter and setter, just not a _user defined_ getter and setter. – GetSwifty Feb 09 '18 at 19:18
  • @PeejWeej I don't agree. I'm happy you've put your point of view in an answer of your own, but my point, which I stick to, is that, as far as meaning is concerned, the language _could_ have used a totally different notation, e.g. `var name: String; var age: Int { writable }`. Instead, and perhaps a bit confusingly, the language just "reused" the `get` and `set` already used for a computer property getter and setter because that's what it had on hand. To all intents and purposes, this is a _different_ `get` and `set`, and that is what has confused the OP. – matt Feb 09 '18 at 19:38
  • While I agree that the verbiage (though well established in the field) could be better, (personally I think `readable` and `writable` would indeed be better) a `get` and `set` _are required_ from an adhering property. Whether manually overridden in the source code, or generated by the compiler. – GetSwifty Feb 09 '18 at 19:45
  • @PeejWeej There is no such thing as a Swift property without a getter, implicitly or explicitly, so the protocol notation could have saved its breath; _any_ `name` String property will be satisfactory. So just `writable` for the `age` property would do, and, as I say, the OP wouldn't have been confused. – matt Feb 09 '18 at 19:54
  • There are swift properties without _visible_ getters, (e.g. any private property), and the current approach allows flexibility to allow setter-only properties in the future without changing the syntax requirements. Regardless, I generally agree with you, but it's untrue that "They have nothing to do with `getter and setter`" – GetSwifty Feb 09 '18 at 20:05
1

One thing to note first: Every property has an implicit getter and setter unless otherwise stated. e.g. a simple var age: Int implicitly has a get and set, and let age: Int implicitly has a get. When you declare a manual getter and setter, you're overriding something, not creating something that didn't otherwise exist.

As for protocols, in explicit terms:

var name: String { get } means the adhering Type must have a property with a signature of name:String that can be read, AKA. get

var age: Int { get set } means the adhering Type must have a property with a signature of age:String that can be read or assigned, AKA get and set

Note that these rules are inclusive not exclusive. The requirements don't care how they are satisfied, and don't disallow anything else.

This means with your given example, a property of let name: String would work because it only requires access, but let age: Int wouldn't work, because it cannot be changed. It also doesn't care about internal details, so using computed properties, private setters, etc. is fine as long as they have the necessary access.

GetSwifty
  • 7,568
  • 1
  • 29
  • 46