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

时间:2018-05-20 15:21:03

标签: swift getter-setter swift-protocols

我正在遵循面向协议的编程范例的教程,其中我对我认为非常简单的东西感到困惑,这些东西只是协议或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"

3 个答案:

答案 0 :(得分:3)

  

如果我把它设置为真正的只读属性,我做错了什么?

协议(一组规则)与采用协议的类型(即您的结构)之间存在差异。

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

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

是非法的将是相反的,即对于声明属性读写的协议,但是采用者将其声明为只读。在你的例子中没有出现这种情况,但如果有的话,编译器就会阻止你。

答案 1 :(得分:1)

来自Docs

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

            ...
            HSSFRow row = worksheet.createRow(i);
            row.createCell(0).setCellValue(name);
            row.createCell(1).setCellValue(phone);
            ...
  

FullyNamed协议需要符合类型才能提供   完全合格的名字。该协议没有指定任何其他内容   符合类型的性质 - 它只指定类型必须   能够为自己提供全名。该协议规定了这一点   任何FullyNamed类型都必须具有一个名为gettable的实例属性   fullName,类型为String

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

答案 2 :(得分:1)

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