简体   繁体   中英

Protocols {get set} : What does get and set allow and disallow in a protocol? Swift

From online learning i learnt that get and set are functions that are called when you get or set a variable. Eg

var test: String { 
       get{
         print("get called")
         return "default"
       }
       set{
       print("Set Called")
       }}

Where when test is called in code Eg something like

print(test)

it will execute the code in get{} and when test is being set as a value eg

test = "hello" 

it calls the set{} code block

Now what I am trying to understand is why in a swift protocol when you put down what variables are needed for example

protocol Car {
   var make:String 
   var licenseNumber: Int
}

you need to have

protocol Car {
   var make:String { get set} 
   var licenseNumber: Int {get set}
}

or

protocol Car {
   var make:String {get}
   var licenseNumber: Int {get}
}

what I want to know is what does the get and set actually do and how is a protocol that has both

{get set}

different to

{get}

Remember that protocols specifies a set of requirements - "things that conform to me have this and that ability", but not how they achieve those abilities.

This syntax:

var make: String

declares a stored property called make . Not only does it mean that "there should be a String property called make that you can get and set", but it also specifies how that property is implemented - namely that it is stored as part of the class/struct, as opposed to computed from other values. You can think of the above as syntactic sugar for:

var make: String 
// everything under this is the "how" part
// what actually happens is a little different - this is for illustrative purposes only
{
    get { return _make }
    set { _make = newValue }
}
private var _make: String

Clearly, protocol members are not supposed to do that.

This syntax

var make: String { get set }

on the other hand, declares no body (the "how" part) for the getter and setter, and so is valid in a protocol. It just says "there should be a String property called make that you can get and set", not saying anything about its implementation details. For example, in one implementation it could be computed from the licenseNumber :

// This implementation doesn't make much sense in real life. 
// The point is to show that you can implement the make property in many ways
// not just by *storing* the make
class MyCar: Car {
    var licenseNumber: Int

    var make: String {
        get {
            if licenseNumber == 1 {
                return "Make 1"
            } else {
                return "Make 2"
            }
        }

        set { // the setter doesn't have to set anything either
            print("The make is being set!")
        }
    }
}

And if you did var make: String { get } instead, the protocol only requires the property to be gettable (but of course implementations can also implement a setter if they want).

The get/set in a protocol variable requirement have nothing to do with the computed property getter and setter functions you showed first.

The get/set in a protocol variable requirement simply states whether this variable is permitted to be read-only/constant (get) or must also be writable (get set).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM