Я знаю private(set)
, как обсуждалось, here и here, но он не работает для моей ситуации, когда у меня есть переменная экземпляра с внутренними свойствами.Доступ только для чтения, например, свойство в Swift
У меня есть свойство экземпляра, где я бы хотел, чтобы он имел доступ только для чтения. Следующий код показывает конкретный пример.
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.
Видимо я все еще могу изменить origin
путем изменения внутренней x
и y
непосредственно, но это не мое намерение.
Как я могу сделать origin
действительно доступным только для чтения? Я что-то упускаю?
Изменение Point
к private var x: Int
или fileprivate var x: Int
не будет работать для меня, потому что я хочу быть в состоянии позволить внешний класс как Sprite
изменить Point
.
Редактировать: Из комментариев ниже, это не мой фактический сценарий, так как кто-то замечает, что я должен использовать CGPoint
. Код служит примером, чтобы сделать мой вопрос более конкретным. У меня на самом деле сложный класс как свойство экземпляра в другом классе, а не этот простой Point
. Я также не могу использовать его как struct
из-за других ограничений конструкции.
Редактирование 2: Ответ ниже указывает на то, что ссылка не может быть изменена. Это ограничение в Swift я только что узнал, потому что, по-видимому, я могу достичь именно то, что я хотел в C++ с использованием Point const &
:
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_. – matt