【问题标题】:Is there a way to declare protocol property as private?有没有办法将协议属性声明为私有?
【发布时间】:2018-12-20 16:46:00
【问题描述】:

我想遵守一个协议,并隐藏其要访问的符合的属性(将它们声明为private)。

考虑以下几点:

protocol P {
    var value: String { get }

    init(value: String)
}

class C: P {
    var value: String

    required init(value: String) {
        self.value = value
    }
}

我会创建一个C 对象:

let myObject = C(value: "Hello World")
myObject.value = "New Value"

基于此,我有两个问题:

现在,如果我尝试将 value 声明为私有:

private var value: String { get }

编译器会报错:

'private' 修饰符不能在协议中使用

带有将private 替换为internal 的修复建议。

如何防止通过说出myObject.value 来访问value?如果没有办法,这个限制的原因是什么?

【问题讨论】:

  • 协议的全部意义在于定义(部分)实现它的类向外界的能力。它不是如何设计和实现一个类的蓝图。所以私有在协议中几乎没有意义。
  • 您不能为仅使用 { get } 的协议中声明的变量设置值。这对我来说按预期工作。抛出的错误是“无法分配给属性:'变量'是一个只能获取的属性”
  • 您的第二个问题在这里得到解答:stackoverflow.com/q/50436344/1187415
  • @MartinR 谢谢。我尝试使用 bool 变量,它按预期工作,所以我认为它也适用于字符串。我的错。
  • 如果这个属性需要是私有的,那么它不应该在协议中。协议是一个接口,它定义了一种可以被许多人而不是一个人采用的公共行为。 Private 限制对特定类型的访问,这违背了接口的全部目的。

标签: swift protocols access-control


【解决方案1】:

符合

protocol P {
    var value: String { get }

    init(value: String)
}

需要具有默认访问权限的可获取属性value。如果写访问 符合类中的属性应仅限于类本身 然后你可以声明它为Swift readonly external, readwrite internal property:

class C: P {
    private(set) var value: String

    required init(value: String) {
        self.value = value
    }
}

let myObject = C(value: "Hello World")
print(myObject.value) // OK
myObject.value = "New Value" // Error: Cannot assign to property: 'value' setter is inaccessible

如果属性应该只在初始化器中设置,那么就让它 一个常量:

class C: P {
    let value: String

    required init(value: String) {
        self.value = value
    }
}

let myObject = C(value: "Hello World")
print(myObject.value) // OK
myObject.value = "New Value" // Error: Cannot assign to property: 'value' is a 'let' constant

【讨论】:

  • 声明为private(set)似乎是明智的,所以没有办法将其声明为private,对吧?
  • @AhmadF: private 将暗示 private(get) 并且不能满足协议要求。 (如果有可能,您可以通过添加协议一致性来使任何私有属性可见,并绕过访问控制。) – 如果有帮助,您可以将 协议和属性文件设为私有或内部。
  • @AhmadF:再次阅读您的评论“我只想从初始化程序中设置更高级别”:在这种情况下,您可以简单地将属性声明为常量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-15
  • 2012-06-19
  • 2021-12-24
  • 1970-01-01
  • 1970-01-01
  • 2016-06-26
相关资源
最近更新 更多