How to conform to a protocol's variables' set & get?

前端 未结 2 1260
谎友^
谎友^ 2021-02-18 23:30

I\'m playing around with protocols and how to conform to them.

protocol Human {    
    var height: Int { get set }    
}

struct Boy: Human { 
    var height: In         


        
2条回答
  •  刺人心
    刺人心 (楼主)
    2021-02-18 23:59

    Prerequisite:

    Go into your playground and just write the snippet below:

    var height: Int {
        get {
            return 5
        }
    }    
    

    or similarly:

    var height: Int {
        return 5
    }    
    

    Try to print height's value, obviously works. So far so good

    print(height) // prints 5
    

    However if you try to set it to a new value then you'll get an error:

    height = 8 // ERROR  
    

    error: cannot assign to value: 'height' is a get-only property


    Answer:

    Based on Martin's answer, I first wrote:

    set(newValue) {
        height = newValue 
    }
    

    Which put a ton of load on my memory and led me to this question. Please take a look. So then I was figuring out what to write, and I kind of understood that if you don't want to do anything special you shouldn't be using computed properties and instead you should just use normal stored properties.

    So I wrote a similar code

    protocol Human {
    
        var height: Float {get set}
    
    }
    
    struct Boy: Human {
    
        // inch
        var USheight : Float
    
        // cm
        var height: Float {
            get {
                return 2.54 * USheight
            }
            set(newValue) {
             USheight = newValue/2.54
    
            }
        }
    }
    
    // 5 ft person
    var person = Boy(USheight: 60)
     // interestingly the initializer is 'only' based on stored properties because they
     // initialize computed properties. 
    
    
    // equals to 152cm person
    print(person.height) // 152.4
    

    Pro tip: When should you should make your properties read-only?

    Normally if you make a property to be read-only ie { get } it's because those properties are computed and you don't want the object to have control over it.

    Example you have a JSON object. It has multiple big objects like:

    JSONData
     - userInfo (name, address, age)
     - devices (iPads, iPhones, Mac books)
     - credentials (basic iCloud, pro iCloud, celebrity)
    

    by making the role a read-only you're only allowing the server to tell the code base the role of the user.

    protocol Credentials {
        var role: String { get }
    
        init(person: Person)
    }
    
    class Person {
        var userInfo: String
        var devices: [String]
        var creds: Credentials {
            Credentials(person: self)
        }
    
        init(userInfo: userInfo, devices: [String]) {
            self.userInfo = userInfo
            self.devices = devices
        }
    }
    

提交回复
热议问题