Solución:
Para mutar el primer elemento del vector, normalmente obtendría una referencia a ese elemento. En otras palabras, una referencia dentro el vector. Y al ser una estructura normal, el vector debe tener un método que le proporcione la referencia.
La cuestión es que una referencia a un vector significa que puede hacer algo con el interior del vector, leerlo o modificarlo de alguna manera. Rust no conoce los detalles, solo sabe que mientras tienes esa referencia, puedes hacer cosas.
Y con esa información limitada, el comprobador de préstamos de Rust intenta evitar que te dispares en el pie. Dice: si vas a leer el vector, bien, puedes leerlo como quieras, incluso puedes hacer que alguna otra función lo lea, o dos funciones, o cinco. Pero no puede modificar el vector mientras lo está leyendo, no es seguro, genera errores. Por lo tanto, puede tener tantas referencias de solo lectura en el vector como desee, pero solo si y cuando no tiene ninguna referencia que se pueda escribir en él. Si tiene una referencia que se pueda escribir, entonces solo puede haber una referencia a la vez.
Por tanto, el tipo de referencia importa. Y es por eso que el vector tiene los dos métodos que le dan el primer elemento: first y first_mut.
Asi que aqui
let mut vec = Vec::new();
su vector ya es mutable. Y viniendo de otros lenguajes, podría trabajar desde la intuición de que si el vector es mutable una vez, es mutable siempre. Algo así como const
valor en C ++ o immutable
en D. Es mutable o no.
Pero en Rust es posible que desee referencias inmutables en una estructura mutable. Por ejemplo, es posible que desee que un hilo funcione en un elemento de un vector y otro hilo en otro elemento, y si prefiere mantener puesto el cinturón de seguridad del comprobador de préstamos, entonces la forma más sencilla de tener varias referencias es mantenerlas inmutables. . Es por eso que métodos como first devuelven referencias inmutables y para obtener una referencia mutable, debe optar explícitamente mediante el uso de un método diferente.
PD: ¿Eso fue de alguna ayuda?
Aquí hay ejemplos de código igualmente funcionales:
vec[0].some_value += 1;
vec.first_mut().unwrap().some_value += 1;
El problema con el código que se muestra en cuestión es que first()
devuelve una referencia (inmutable) al primer elemento, pero se requiere una referencia mutable.
Indexación ([0]
) funciona así:
-
vec
derefs para cortar - indexación en llamadas de segmento
index_mut
método deIndexMut
rasgo -
index_mut
El método devuelve una referencia mutable (&mut someType
)
Creo que estas buscando &mut
al tomar referencia.
#[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);
}
Nota {}
alrededor de la referencia del elemento mutable. Es necesario limitar el alcance de referencia mutable. No se pueden tener referencias mutables e inmutables al mismo tiempo: println!
fallaría mientras third
todavía está en alcance.