协议var {get}

api*_*nho 3 protocols ios swift

每当使用带有getter的var声明协议时,我认为这意味着var可以从类内部设置,而不是从外部设置,因为没有"setter".

游乐场代码

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
Run Code Online (Sandbox Code Playgroud)

如果您仍然可以更改其值,那么宣布{get}的意义何在?

Rob*_*ier 5

RunningAnimal作出积极承诺:您必须为limbs物业和topSpeed物业提供吸气剂.它没有做出任何"负面承诺".它并不表示您无法为这些属性提供setter.您可以提供所需的任何其他方法或访问者.

也就是说,这里的协议几乎无关紧要.cheetah是类型Cheetah,并Cheetah具有内部可用的设置器limbs.

如果您更改此代码以使用协议类型,那么您将受限于协议所承诺的内容:

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

在您的特定示例中,您几乎肯定只能创建limbs一个let变量.您可以自由地使用a let来履行var {get}承诺:

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
Run Code Online (Sandbox Code Playgroud)

在更一般的情况下,您希望属性是可私密写入的,您可以将setter标记为private:

class Cheetah: RunningAnimal {
    let limbs = 4
    private(set) var topSpeed = 120
}
Run Code Online (Sandbox Code Playgroud)

你甚至可以计算你的属性,并且仍然符合RunningAnimal:

class Cheetah: RunningAnimal {
    var limbs: Int { return 4 }
    var topSpeed: Int { return 120 }
}
Run Code Online (Sandbox Code Playgroud)

只要您根据需要提供getter和setter,协议并不真正关心如何实现属性.(这不适用于函数.协议函数要求必须作为方法实现.它们不能实现为相同类型的闭包属性.)