"public private(set)" 访问修饰符是如何工作的?

61

所以我在这里阅读苹果的文档 - 苹果文档

然后我遇到了这个:

public struct TrackedString {
    public private(set) var numberOfEdits = 0
    public var value: String = "" {
        didSet {
            numberOfEdits += 1
        }
    }
    public init() {}
}

public private(set)是如何起作用的?如果您能提供一些更简单的示例/解释,那将是非常棒的!

4个回答

79

这只是表示numberOfEdits的getter是公共的,但setter是私有的。没有更多的东西。

之所以在这种情况下这么做是为了让您可以公开读取numberOfEdits,但只能通过更改value来设置它。如果它完全是public,那么任何人都可以设置它,但如果它只是可设置的,那么value中的didSet无法修改它。private(set)是这两者之间的妥协。


1
解释是正确的,但提到的变量是错误的。numberOfEdits属性是只能从类内部设置的属性(即在其他任何地方都是只读的)。value属性在任何地方仍然是可读/可写的。 - ghostatron
3
“numberOfEdits属性只能从类内部进行设置”,不是从类,而是从文件。在Swift中,尚未实现对类作用域隐私的支持。” - matt

25

这个属性可以被读取,但不能从外部设置。

通过写入private(set)来分配较低的访问级别。

它的作用类似于公共getter私有setter

//MARK:- Foo
class Foo {
    private var name: String
    private var ID: String

   //initialize
   init(name:String, ID:String){
      self.name = name
      self.ID = ID
   }
}

当试图访问private变量时,我们会收到一个错误。

privateAccessLevel

但是我们可以通过将private访问级别更改为private(set)来在一行代码中解决此错误。

//MARK:- Foo
class Foo {
    private(set) var name: String
    private var ID: String

   //initialize
   init(name:String, ID:String) {
       self.name = name
       self.ID = ID
   }
}

因此,您可以轻松访问私有变量、常量、属性或下标。

//Access class value from Foo
let fooObjc = Foo.init(name: "test", ID: "9900")
print(fooObjc.name)

使用fileprivate(set)private(set)internal(set),可以像为计算属性中的显式setter一样改变此合成setter的访问级别。

该属性可以被读取,但无法从外部设置。

参考:单击链接了解更多信息


2
在你的最后一个例子中,private(set) var 实际上是 let。只有当值将在类内部被修改时(init 方法不算),private(set) var 才有用。 - vadian
它对我有用,非常感谢您的帮助。 此外,如果您想要这个变量在 Objective-C 和 Swift 中公开可读,并且可以私下设置,则可以执行以下操作: @objc public private(set) var myVar: String = "" - Syed Faizan Ahmed

3

private (set) var 可以限制写入内部范围,但仍然允许读取外部访问。变量也可以在内部读取。

例如,比较 private varprivate (set) var

private

class NameNotAccessible {
    private var name: String?
}

var person = NameNotAccessible()
print(person.name) // ERROR: external access forbidden

修改为private (set) var

class NameAccessible {
    private (set) var name: String? // externally readable, internally writable
}

var person2 = NameAccessible()
print(person2.name) // external read OK
person2.name = "Jacob" // ERROR: external write forbidden

1

感谢@Sivabalaa Jothibose和@craft,这对我很有帮助,非常感谢你们的帮助。

此外,如果您想要将此变量公开可读(Objective-C和Swift)并私下设置,则可以执行以下操作:

@objc public private(set) var myVar: String = ""

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接