Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protocols var {get}

Whenever a protocol is declared with a var with a getter only I thought that would mean that the var would be settable from inside the class and not from the outside since there is no "setter".

Playground code

protocol RunningAnimal{
    var limbs:Int { get }
    var topSpeed:Int{ get }
}

class Cheetah:RunningAnimal {
    var limbs = 4
    var topSpeed = 120
}

let cheetah = Cheetah()
cheetah.limbs = 100
print("cheetah limbs ->\(cheetah.limbs)") //prints 100

Whats the point of declaring {get} if you can still change its value?

like image 720
apinho Avatar asked Jul 01 '26 22:07

apinho


1 Answers

RunningAnimal makes a positive promise: you must provide getters for a limbs property and a topSpeed property. It does not make any "negative promises." It doesn't say that you can't provide a setter for these properties. You can provide any other methods or accessors you want.

That said, the protocol here is pretty much irrelevant. cheetah is of type Cheetah, and Cheetah has an internally available setter on limbs.

If you changed this code to use the protocol type, then you would be restricted to what the protocol promises:

let cheetah: RunningAnimal = Cheetah()
cheetah.limbs = 100 // error: cannot assign to property: 'limbs' is a get-only property

In your particular example, you should almost certainly just make limbs a let variable. You are free to use a let to fulfill a var {get} promise:

class Cheetah: RunningAnimal {
    let limbs = 4
    let topSpeed = 120
}

let cheetah = Cheetah()
cheetah.limbs = 100 // error: cannot assign to property: 'limbs' is a 'let' constant

In the more general case where you want the property to be privately writable, you can just mark the setter private:

class Cheetah: RunningAnimal {
    let limbs = 4
    private(set) var topSpeed = 120
}

You even could make your properties computed, and still conform to RunningAnimal:

class Cheetah: RunningAnimal {
    var limbs: Int { return 4 }
    var topSpeed: Int { return 120 }
}

Protocols don't really care how you implement properties, as long as you provide a getter and setter as required. (This doesn't apply to functions. Protocol function requirements must be implemented as a method. They cannot be implemented as a closure property of the same type.)

like image 106
Rob Napier Avatar answered Jul 03 '26 11:07

Rob Napier



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!