【发布时间】:2017-06-18 08:29:57
【问题描述】:
我知道private(set) 讨论过here 和here,但它似乎不适用于我有具有内部属性的实例变量的情况。
我有一个实例属性,我希望它具有只读访问权限。以下代码显示了一些具体示例。
class Point {
var x: Int
var y: Int
init(_ x: Int, _ y: Int) {
self.x = x
self.y = y
}
}
class Sprite {
private(set) var origin = Point(0,0)
func incrementX() {
origin.x += 1
}
func incrementY() {
origin.y += 1
}
}
在这里,我的意图是让Sprite 成为origin 的唯一所有者,让它成为唯一可以修改它的人,否则使origin 对公众只读。然而:
var sprite = Sprite()
sprite.origin = Point(100, 200) // Error: setter is inaccessibie. Expected behavior.
sprite.origin.x = 150 // No error. The origin.x will be set to 150.
显然我仍然可以通过直接修改内部x和y来修改origin,但这不是我的意图。
如何使origin 真正只读?我错过了什么吗?
将Point 修改为private var x: Int 或fileprivate var x: Int 对我不起作用,因为我希望能够让Sprite 这样的外部类修改Point。
编辑:从下面的评论来看,这不是我的实际情况,因为有人认为我应该使用CGPoint。该代码作为示例,使我的问题更加具体。我实际上在另一个类中有一个复杂的类作为实例属性,而不是这个简单的Point。由于其他设计限制,我也不能将其用作struct。
Edit2:下面的答案指出您不能阻止引用是可变的。这是我刚刚学到的 Swift 的一个限制,因为显然,我可以使用 Point const & 在 C++ 中实现我想要的:
class Point {
public:
int x;
int y;
Point(int _x, int _y) {
x = _x;
y = _y;
}
Point & operator=(const Point & rhs) {
x = rhs.x;
y = rhs.y;
return *this;
}
...
};
class Sprite {
Point origin;
public:
Sprite()
: origin(0,0)
{}
// HERE
Point const & getOrigin() const { return origin; }
void incrementX() { origin.x += 1; }
void incrementY() { origin.y += 1; }
};
int main(int argc, const char * argv[]) {
Sprite sprite = Sprite();
Point const & o = sprite.getOrigin();
cout << "o: " << o << endl; // (0,0)
// o.x = 10; // Error: Cannot assign to const-qualified type.
// o = Point (100, 200); // Error: no viable overlaod =.
sprite.incrementX();
cout << "o: " << o << endl; // (1,0). Swift can't get this behavior with `struct Point`, but it won't prevent some writing attempts with `class Point`.
cout << "sprite.origin: " << sprite.getOrigin() << endl; // (1,0).
return 0;
}
【问题讨论】:
-
这不是“类属性”。它是一个 instance 属性。
标签: swift properties readonly access-control