问题:
有没有办法防止类实例(引用类型)被修改?
原因:
问这个的原因是因为当一个类实例的引用传递给一个函数时,该函数可能会无意中修改该实例。
注意: 使用let或private function / property可防止完全访问外部世界。问题是如何防止正常的类实例被函数修改。
我希望得到像C ++中可用的东西。
相当于我要求的C ++代码:
const CA * ca1; //This is C++ and was hoping for something like this in swift
代码:
class CA {
var x1 : Int = 10
func modify() {
x1 = 99
}
}
let ca1 = CA()
ca1.x1 = 30 //Is there a way I can prevent ca1 from this from being modified ?
ca1.modify() //Is there a way I can prevent ca1 from this from being modified ?
//This function should not modify the CA instance
func display(#ca : CA) {
ca.x1 = 30 //Is there a way I can prevent ca from this from being modified ?
ca.modify() //Is there a way I can prevent ca from this from being modified ?
println("ca.x1 = \(ca.x1)")
}
答案 0 :(得分:2)
您可以使该属性具有内部(默认访问)getter和私有setter。这样,其他类可以读取值但不能修改它,只有你的类可以修改它。
class Test {
private(set) var x1 : Int = 0
func increaseX1() {
x1++
}
}
let t = Test()
print(t.x1) // 0
t.increaseX1()
print(t.x1) // 1
t.x1 = 2 // error: Cannot assign to 'x1' in 't'
请注意,如果您在操场上尝试此操作,则可以指定t.x1
,因为"私人"在Swift中不完全私有:相同源文件中的代码可以访问它。
要使getter公开而不是内部,您可以:
public private(set) var x1 : Int = 0
// or:
private(set) public var x1 : Int = 0
编辑:既然我理解了您的意图,那么解决Swift不支持const
机制的问题是解决问题的一种方法 - 仅仅是C ++的作用:创建一个只有let
常量的辅助结构,并提供一个返回这样一个帮助器的函数。我只对那些只有很少实例变量的类使用它(你不想用一个有几十个的类来做):
struct ConstCA {
let x1 : Int
}
class CA {
var x1 : Int = 10
func modify() {
x1 = 99
}
func getConstCA() -> ConstCA {
return ConstCA(x1 : x1)
}
}
func display(#ca : ConstCA) {
// Can only read `x1` but cannot modify it.
}
答案 1 :(得分:1)
class CA {
如果您将var
设为let
,那么modify()
都不能更改它。
let x1: Int = 10 // wrong, can't be modified neither internally.
正确的解决方案是制作x1
private
,现在您只能从此处访问它。如果您尝试在项目的其他位置访问x1
,则会收到错误:'CA' does not have a member named 'x1'
private var x1: Int = 10 // correct, class objects can change it, instances can not.
func modify() {
x1 = 99
}
}
如果您不想同时访问类实例变量中的modify()
函数,那么也只是private
。
另外供您参考,我发现本文以非常简洁的方式解释了访问控制:Access Control in Swift
答案 2 :(得分:0)
您始终可以使用let来创建无法修改的常量
let x1 : Int = 10
或者您可以使用getter实现它:
var x1 : Int {
get {
return 10
}
}
通过使用此功能,您只能访问getter,因此您无法修改变量。