如何更改Rust中向量中元素的字段?

如何更改Rust中向量中元素的字段?,rust,Rust,我有一个结构类型的vec,我想更改向量中第一个元素的一些字段。我该怎么做 例如: struct SomeType { some_value: i32, } fn main() { let mut vec = Vec::new(); let mut t = SomeType { some_value: 45 }; vec.push(t); println!("Old value: {}", vec.first().unwrap().some_value)

我有一个结构类型的
vec
,我想更改向量中第一个元素的一些字段。我该怎么做

例如:

struct SomeType {
    some_value: i32,
}

fn main() {
    let mut vec = Vec::new();
    let mut t = SomeType { some_value: 45 };
    vec.push(t);

    println!("Old value: {}", vec.first().unwrap().some_value);
    vec.first().unwrap().some_value += 1;
    println!("New value: {}", vec.first().unwrap().some_value);
}
这无法编译:

错误:无法分配给不可变字段
-->向量rs:15:2
|
15 |向量优先().展开().某些值+=1;
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^无法可变借用不可变字段

我还不能理解锈迹中的易变性;这里的正确方法是什么?

要对向量的第一个元素进行变异,通常会得到该元素的引用。换句话说,一个引用进入向量。作为一个正常的结构,向量需要有一个方法来为你们提供参考

#[derive(Debug)]
struct Character{
    name: String,
}

fn main() {
    let mut hobbits = vec![
        Character{name:String::from("Sam")},
        Character{name:String::from("Merry")},
        Character{name:String::from("Pepper")},
    ];

    {
        let third = &mut hobbits[2];
        third.name = String::from("Pippin");
    }

    println!("{:?}", hobbits);
}
问题是,对向量的引用意味着你可以用向量的内部做一些事情,阅读它们或者以某种方式修改它们。Rust不知道细节,它只知道当你持有参考资料时,你可以做一些事情

仅凭这些有限的信息,借来的铁锈检查人员试图阻止你射中自己的脚。它说:如果你要读取向量,好吧,你可以用任何方式读取它,你甚至可以让其他函数读取它,或者两个函数,或者五个函数。但是你不能在读向量的时候修改它,这是不安全的,它会导致错误。因此,您可以在向量中拥有任意数量的只读引用,但前提是您没有在其中保存任何可写引用。如果您持有一个可写引用,那么一次只能有一个这样的引用

因此,参考资料的种类很重要。这就是为什么向量有两种方法,给你第一个元素:和

所以这里

let mut vec = Vec::new();
你的向量已经是可变的了。从其他语言中,你可以凭直觉得出,如果向量是可变的,那么它总是可变的。在C++中,类似于<代码> const <代码>值> C++ >代码>不可更改的< /代码>。 但在Rust中,您可能希望将不可变引用转换为可变结构。例如,您可能希望一个线程处理向量的一个元素,另一个线程处理另一个元素,如果您希望保持借用检查器的安全带,那么拥有多个引用的最简单方法就是保持它们不变。这就是为什么像返回不可变引用和获取可变引用这样的方法需要使用不同的方法显式地选择加入


还有,这有什么帮助吗?

以下是同样有效的代码示例:

vec[0].some_value += 1;

vec.first_mut().unwrap().some_value += 1;
问题中显示的代码的问题是
first()
返回对第一个元素的(不可变)引用,但需要可变引用

索引(
[0]
)的工作原理如下:

  • vec
    derefs到切片
  • 对来自
    IndexMut
    trait的片调用
    index\u mut
    方法进行索引
  • index\u mut
    方法返回可变引用(
    &mut someType

  • 我想你在参考时是在寻找
    &mut

    #[derive(Debug)]
    struct Character{
        name: String,
    }
    
    fn main() {
        let mut hobbits = vec![
            Character{name:String::from("Sam")},
            Character{name:String::from("Merry")},
            Character{name:String::from("Pepper")},
        ];
    
        {
            let third = &mut hobbits[2];
            third.name = String::from("Pippin");
        }
    
        println!("{:?}", hobbits);
    }
    

    注意可变元素引用周围的
    {}
    。需要限制可变引用范围。不能同时具有可变引用和不可变引用:
    println第三个
    仍在范围内时,code>将失败。

    这是一个老问题。我最近刚开始生锈,我想试着回答这个问题

    要更新第一个元素,我将执行以下操作:

    让mut st=&mut vec[0];
    st.U值+=1;
    
    或者只是:

    vec[0]。某些_值+=1;
    
    要完全替换第一个元素,我可以执行以下操作:

    std::mem::replace(&mut-vec[0],SomeType{some_值:111});
    
    您也可以通过以下方式执行此操作:

    fn changeValues(mut list: Vec<i32>){
            println!("Before value change: {:?}", list.get(0).unwrap());
            list[0] = 3;
            println!("After value change: {:?}", list.get(0).unwrap());
        }
    
    fn更改值(mut列表:Vec){
    println!(“值更改之前:{:?}”,list.get(0.unwrap());
    列表[0]=3;
    println!(“值更改后:{:?}”,list.get(0.unwrap());
    }
    
    感谢您的详细解释!事实上,我从C++中尝试处理类似于 CONST 的事情,现在我更了解了。谢谢这些例子,这比预期的要简单。我希望你不介意我接受了ArtemGr的回答,因为他提供了非常详细的解释。