如何防止类实例被修改?

时间:2015-02-21 13:57:04

标签: swift

问题:

有没有办法防止类实例(引用类型)被修改?

原因:

问这个的原因是因为当一个类实例的引用传递给一个函数时,该函数可能会无意中修改该实例。

注意: 使用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)")
}

3 个答案:

答案 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,因此您无法修改变量。