不寻常的 Swift 成语 - 它有什么作用?

Unusual Swift Idiom - what does it achieve?

我正在阅读一本关于 Swift 设计模式的书,并且遇到了一个示例,作者希望确保任何人初始化特定 [=17= 的子class ] 必须传入一个base需要的值class:

class Employee {
    private var professionBV: String // BV = backingVariable

    private init(profession: String) {
        self.professionBV = profession
    }

    final var profession: String {
        return professionBV
    }
}

// Even if you create your own init here, you always have to pass in a
// value for profession
class Nurse: Employee { }

我不明白的是作者通过将支持变量与计算 属性 结合使用获得了什么。不就相当于这样吗:

// Remove the backing variable, mark profession as final - what have I lost?
class Employee {
    final private var profession: String

    private init(profession: String) {
        self.profession = profession
    }
}

你是对的 - 如果没有 setter 并且没有额外的处理逻辑,你从这种“支持变量”方法中获得的收益很少。这只是混乱。如果稍后你发现你想在 class 用户和实际存储的变量之间放置一些逻辑,你总是可以将它切换到计算的 属性 然后(或添加一个 willSet/didSet).事实上,如果值在初始化后是不可变的,它应该用 let 而不是 var 来声明。这听起来像是来自 Java 或 C# 程序员的建议,将这些语言的实践应用到 Swift。

出于兴趣,这是什么书?

第一个示例使 profession 变量可在任何地方读取 - 只有写访问(通过支持变量)被限制在定义了 Employee class 的同一个文件中。第二个例子也阻止它从其他文件中读取。

但现在有更好的可能性来实现这一目标 - 您可以为 setter:

配置不同的访问修饰符
class Employee {
     private(set) final var profession : String
}

这使 getter 具有默认权限,但 setter 需要相同的文件。