2014-05-19 2 views
3

Итак, по-видимому, в последних версиях Rust вы не указываете изменчивость внутри struct, но наследуется от корня. Замечательно. Но мне было интересно, можно ли заставить поле всегда неизменно, даже когда корень изменен.Принудительное неизменяемое поле структуры в Rust

Что-то вроде:

struct A { 
    immut s: Shape; // immutable by design 
    bla: Bla; // this field inheriting (im)mutability 
} 
let mut a = make_a(); 
a.s = ...; // illegal 

Это поможет поддерживать хорошие семантические ограничения в программе, так же, как final в Java делает (в очень ограниченном объеме).

Кроме того, мы могли себе представить такого род struct имея некоторые не владеющую ссылку на внутренние неизменные данные, воспользовавшись этой неизменность ...

+0

Ну, если вы сделаете это 'priv' и не изменять его в любом коде внутри того же модуля, что * это * эффективно неизменно. И, конечно, всегда можно заменить 'a' wholesale (' a = make_another_a(); '), что может быть или не быть проблемой. – delnan

ответ

3

Невозможно иметь неизменность одного поля. Был такой вариант в древнем version of Rust (думаю, до 0,8), но он был отброшен, потому что правила путали LOT. Смущать, как вы могли бы спросить? Подумайте об этом так, если поле объявлено изменчивым, а struct объявляется изменчивым, а ссылка используется как &, тогда поле _______.

Лучшее, что отметил Кевин Балларад, состоит в том, что вы можете объявить свое поле Shape частным и сделать метод геттера с использованием impl A {...}.

struct A { 
    priv s: Shape; // can't be seen outside of module 
    bla: Bla; // this field inheriting (im)mutability 
} 

let mut a = A::new(); 
a.s = ...; // illegal 
println!(a.s) //also illegal 
println!(a.getS()) // could be made to serve as a read-only method 

Также есть предложение в Русте, что может упасть понятие изменяемости и неизменности полностью (вы не можете сказать структура не меняется). См. Niko's explanation для этого изменения.

Для получения дополнительной информации о

+0

Хорошо, я понимаю, это может сбить с толку. Из любопытства, каково было фактическое поведение при взятии & A и попытка изменить его поле? Я предполагаю, что это было бы невозможно, так как неизменность является глубокой (унаследованной) ... –

+0

Здесь вы найдете подробное объяснение по kibwen: http://www.reddit.com/r/rust/comments/264d2t/history_question_why_was_mut_from_structsclasses/ –

+0

@ LP_ В принципе, вы унаследовали изменчивость полей структуры. Например. 'struct Foo {priv mut stuff}' может быть изменен, поэтому, например, 'let a = & Foo {stuff: 2}' может быть изменен с использованием 'a.stuff = 3'. Вы никогда не могли гарантировать, что поле будет неизменным, и как вы могли? –

3

Вы не можете заставить неизменность на поле. Как бы структура изменила свою собственную ценность, когда это необходимо?

Что вы можете сделать, это сделать поле частным и разоблачить метод getter, чтобы вернуть ссылку на него (или скопировать/клонировать значение).

+4

Не всегда имеет смысл мутировать данные; вы слышали о функциональном программировании, например? Модификатор Java 'final' можно считать бесполезным, поскольку простой геттер может выполнить тот же эффект. Это просто вопрос упрощения (чтобы люди делали это более естественно - всегда полезно избегать бесполезных потенциальных состояний в коде) и более ясным (автоматическое документирование того, что значение никогда не изменится, может быть полезно). –

Смежные вопросы