Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/108.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 协议var{get}_Ios_Swift_Protocols - Fatal编程技术网

Ios 协议var{get}

Ios 协议var{get},ios,swift,protocols,Ios,Swift,Protocols,无论何时,只要使用带有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(

无论何时,只要使用带有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

如果仍然可以更改{get}的值,那么声明{get}有什么意义呢?

vars的默认访问权限是内部的,因此您应该将其更改为private,以防止外部的任何东西更改它(如果这是您想要的)

不过,协议本身只需要有一个返回某些内容的计算属性。它只是告诉你创建一个返回Int的东西。有几种方法可以满足这个要求

您可以创建一个名为frameds的getter,然后拥有一个不能从外部更改的内部属性

 var limbs:Int { 
         return _limbs
 }
而且四肢本身是私人的

 private var _limbs:Int

RunningAnimal
做出了积极的承诺:您必须为
frameds
属性和
topSpeed
属性提供getter。它不会做出任何“消极承诺”,也不会说您不能为这些属性提供setter。您可以提供所需的任何其他方法或访问器

这就是说,这里的协议几乎是无关紧要的
cheetah
属于
cheetah
类型,并且
cheetah
四肢上有一个内部可用的setter

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

let cheetah: RunningAnimal = Cheetah()
cheetah.limbs = 100 // error: cannot assign to property: 'limbs' is a get-only property
在您的特定示例中,几乎可以肯定的是,您应该将
frameds
设置为
let
变量。您可以自由使用
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
在更一般的情况下,如果希望属性是私有可写的,则只需将setter标记为private:

class Cheetah: RunningAnimal {
    let limbs = 4
    private(set) var topSpeed = 120
}
您甚至可以计算属性,并且仍然符合
RunningAnimal

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

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

如果您只想提供公共getter和私有setter,则不需要私有backing var/计算getter方法。只需使用
private(set)
access修饰符即可。@rickster我提到过有不同的方法可以做到这一点,我试图回答他的问题,但没有太多困惑,不过看起来Rob Napier说得更雄辩,我可以