在Rust中,您没有在struct中指定可变性,但它是从变量绑定继承的.这很好,但是即使根是可变的,也有可能强制一个字段是always不可变的吗?

类似于这种假设的语法:

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

这将有助于在程序中保持良好的语义限制,就像Java的final一样(以非常有限的方式).

此外,我们可以想象这样的struct具有一些对内部不可变数据的非所有权引用,利用这种不可变性...

推荐答案

不可能有一个字段的不变性.这在古代的version of Rust人中是一个选项(想想0.8之前的情况),但它被取消了,因为这些规则让很多人感到困惑.你可能会问,这有多让人困惑?这样想:如果一个字段被声明为可变的,而struct被声明为可变的,并且所使用的引用是不可变的引用(&),那么这个字段就是_______.

最好的方法是将Shape字段声明为private,并使用impl A {...}生成getter方法.

mod inner {
    pub struct A {
        s: i32, // can't be seen outside of module
        pub bla: i32,
    }

    impl A {
        pub fn new() -> Self {
            Self { s: 0, bla: 42 }
        }

        pub fn get_s(&self) -> i32 {
            self.s
        }
    }
}
let mut a = inner::A::new();
a.s = 42; // illegal
println!("{}", a.s); // also illegal
println!("{}", a.get_s()); // could be made to serve as a read-only method
error[E0616]: field `s` of struct `main::inner::A` is private
  --> src/main.rs:20:5
   |
20 |     a.s = 42; // illegal
   |     ^^^

error[E0616]: field `s` of struct `main::inner::A` is private
  --> src/main.rs:21:20
   |
21 |     println!("{}", a.s); // also illegal
   |                    ^^^

有一个命题可能会彻底抛弃易变性和不变性的概念(你不能说 struct 永远不会改变).这一变化见Niko's explanation.

Rust相关问答推荐

如何使用 list 在Rust for Windows中编译?

使用Clap时如何将String作为Into Str参数传递?

在Rust中宏的表达式中提取对象

支持TLS的模拟HTTP服务器

在铁 rust 中传递所有权

在Rust内联程序集中使用字符串常量

信号量释放后 Rust 输出挂起线程

具有多个键的 HashMap

std mpsc 发送者通道在闭包中使用时关闭

如何正确使用git2::Remote::push?

为什么这个闭包没有实现Fn?

中文优化标题:跳出特定循环并返回一个值

枚举的利基优化如何在 Rust 中工作?

判断对象是 PyDatetime 还是 Pydate 的实例?

强制特征仅在 Rust 中的给定类型大小上实现

改变不实现克隆的 dioxus UseState struct

如何解析 Rust 中的 yaml 条件字段?

在 Rust 中枚举字符串的最佳方式? (字符()与 as_bytes())

在 Rust 中有条件地导入?

返回 &str 但不是 String 时,borrow 时间比预期长