Swift 为什么允许我使用继承协议的结构设置协议的只读属性?

Swift 为什么允许我使用继承协议的结构设置协议的只读属性?,swift,getter-setter,swift-protocols,Swift,Getter Setter,Swift Protocols,我正在学习一个关于面向协议编程范例的教程,在这个教程中,我被一些我认为非常简单的东西弄糊涂了,那就是协议或getter和setter的只读属性。我的理解是,在协议中声明变量时,使用关键字“get”表示只读属性。我很兴奋,所以我很快创建了一个游乐场,看看我的想法是否准确,但似乎我仍然可以更改我认为是只读的属性。如果我无法将它设置为真正的只读属性,那么我做错了什么 protocol FullName { var firstName: String {get set} var last

我正在学习一个关于面向协议编程范例的教程,在这个教程中,我被一些我认为非常简单的东西弄糊涂了,那就是协议或getter和setter的只读属性。我的理解是,在协议中声明变量时,使用关键字“get”表示只读属性。我很兴奋,所以我很快创建了一个游乐场,看看我的想法是否准确,但似乎我仍然可以更改我认为是只读的属性。如果我无法将它设置为真正的只读属性,那么我做错了什么

protocol FullName {
    var firstName: String {get set}
    var lastName: String {get set}
    var readOnlyProperty: String {get}

}

struct OuttaBeerOuttaHere: FullName {
    var firstName: String

    var lastName: String

    var readOnlyProperty: String = "Jack! Jack!...Line from Titanic"

}

var leonardoDicaprio = OuttaBeerOuttaHere.init(firstName: "Leonardo", lastName: "Dicaprio", readOnlyProperty: "WTF")

print(leonardoDicaprio.readOnlyProperty) //prints "WTF"

leonardoDicaprio.readOnlyProperty = "what now"

print(leonardoDicaprio.readOnlyProperty) //prints "what now"

以下是具有单实例属性要求的协议示例:

protocol FullyNamed {
    var fullName: String { get }
}
FullyNamed协议需要一个一致的类型来提供 完全限定名。协议没有指定任何其他有关的内容 一致性类型的性质它仅规定该类型必须 能够提供自己的全名。议定书规定: 任何FullyNamed类型都必须具有名为 fullName,类型为String

这是协议的要求,而不是定义

以下是具有单实例属性要求的协议示例:

protocol FullyNamed {
    var fullName: String { get }
}
FullyNamed协议需要一个一致的类型来提供 完全限定名。协议没有指定任何其他有关的内容 一致性类型的性质它仅规定该类型必须 能够提供自己的全名。议定书规定: 任何FullyNamed类型都必须具有名为 fullName,类型为String


这是协议中的一项要求,而不是定义

您的协议没有将
readOnlyProperty
声明为只读属性。它只要求该协议的实现至少具有gettable
readOnlyProperty
属性。是否允许该属性的突变取决于实现本身。

您的协议没有将
readOnlyProperty
声明为只读属性。它只要求该协议的实现至少具有gettable
readOnlyProperty
属性。是否允许该属性的突变取决于实现本身

如果我无法将它设置为真正的只读属性,那么我做错了什么

protocol FullName {
    var firstName: String {get set}
    var lastName: String {get set}
    var readOnlyProperty: String {get}

}

struct OuttaBeerOuttaHere: FullName {
    var firstName: String

    var lastName: String

    var readOnlyProperty: String = "Jack! Jack!...Line from Titanic"

}

var leonardoDicaprio = OuttaBeerOuttaHere.init(firstName: "Leonardo", lastName: "Dicaprio", readOnlyProperty: "WTF")

print(leonardoDicaprio.readOnlyProperty) //prints "WTF"

leonardoDicaprio.readOnlyProperty = "what now"

print(leonardoDicaprio.readOnlyProperty) //prints "what now"
协议(一组规则)和采用该协议的类型(即您的结构)之间存在差异

  • 您的协议规则规定,
    readOnlyProperty
    应该是可读的

  • 您的结构通过使其可读并使其可写来遵守。这并不是非法的,所以一切都很好,并且结构中的
    readOnlyProperty
    是读写的

反之亦然,即协议声明一个属性为读写,而采用者声明该属性为只读。这种情况在您的示例中没有出现,但如果出现,编译器会阻止您

如果我无法将它设置为真正的只读属性,那么我做错了什么

protocol FullName {
    var firstName: String {get set}
    var lastName: String {get set}
    var readOnlyProperty: String {get}

}

struct OuttaBeerOuttaHere: FullName {
    var firstName: String

    var lastName: String

    var readOnlyProperty: String = "Jack! Jack!...Line from Titanic"

}

var leonardoDicaprio = OuttaBeerOuttaHere.init(firstName: "Leonardo", lastName: "Dicaprio", readOnlyProperty: "WTF")

print(leonardoDicaprio.readOnlyProperty) //prints "WTF"

leonardoDicaprio.readOnlyProperty = "what now"

print(leonardoDicaprio.readOnlyProperty) //prints "what now"
协议(一组规则)和采用该协议的类型(即您的结构)之间存在差异

  • 您的协议规则规定,
    readOnlyProperty
    应该是可读的

  • 您的结构通过使其可读并使其可写来遵守。这并不是非法的,所以一切都很好,并且结构中的
    readOnlyProperty
    是读写的

反之亦然,即协议声明一个属性为读写,而采用者声明该属性为只读。您的示例中没有出现这种情况,但如果出现这种情况,编译器会阻止您。

FYI-您的结构不会“继承”协议。它“符合”协议。仅供参考-您的结构不会“继承”协议。它“符合”协议。