Struct Rust中结构的字段可变性

Struct Rust中结构的字段可变性,struct,rust,mutability,Struct,Rust,Mutability,我还是个新手,但我对结构中字段的易变性有疑问。特别是我们如何修改最初不可变的字段。例如: struct Point { x: isize, y: isize, } impl Point { fn new(x: isize, y: isize) -> Self { Self { x, y } } fn set_x(&mut self, new_x: isize) { self.x = new_x; }

我还是个新手,但我对结构中字段的易变性有疑问。特别是我们如何修改最初不可变的字段。例如:

struct Point {
    x: isize,
    y: isize,
}

impl Point {
    fn new(x: isize, y: isize) -> Self {
        Self { x, y }
    }
    fn set_x(&mut self, new_x: isize) {
        self.x = new_x;
    }
}

struct Line {
    p: Point,
    q: Point,
}

impl Line {
    fn new(p: Point, q: Point) -> Self {
        Self { p, q }
    }
    fn set_x_in_p(&mut self, new_x: isize) {
        self.p.set_x(new_x);
    }
}

fn main() {
    // Both x and y are immutable
    let p = Point::new(0, 0);
    let q = Point::new(1, 1);

    // Line IS mutable
    let mut line = Line::new(p, q);

   // Modifying point p (originally immutable) with a new x 
    line.set_x_in_p(999);
}
相反,我们不能使用引用

   let x = 3;
   let y = &mut x; // does not work because x originally is immutable

那么,它是如何工作的呢?谢谢。

当您声明
x
时,您使用
let
而不是
let mut
将其指定为不可变。然后,当您声明
y
并将其初始化为
&mut x
时,您正试图借用
x
。在Rust中,你永远不能同时拥有共享所有权和易变性


查看有关所有权的信息。

在您的示例中,
p
q
确实是不可变的,但是您可以使用构造函数将它们移动到
实例中,因为它们是按值传递的,并且不实现
Copy
来启用隐式复制。这意味着原始绑定(
p
q
)不再有效(编译器将阻止您使用它们),而只能通过可变
绑定访问值,该绑定允许对其成员进行变异。本质上,可变的不是值,而是它们的绑定。例如,以下代码可用于重新绑定值以更改其易变性:

let x = String::from("hello world"); // using String as an example of a non-Copy type

let mut x = x; // this shadows the previous binding with a mutable one of the same name
x.make_ascii_uppercase(); // we can now mutate the string
let x = x; // shadow the mutable binding with an immutable one

println!("Result: {}", x);
此示例之所以有效,是因为我们可以直接控制该值,并且可以根据需要移动/绑定它。引入引用将限制可以做的事情-例如,以下示例不起作用:

let x = String::from("hello world");
let x_ref = &x; // create an immutable reference to x
let mut x_mut = x; // error - we can't move x while it's borrowed
let x_mut_ref = &mut x; // error - we can't create a mutable reference while any other references exist
我建议阅读Rust by example的页面,这很好地解释了这一点