reference - ps4 - rust traduccion
No se puede mover fuera del contenido prestado al intentar transferir la propiedad (1)
No se puede mover fuera del contenido prestado al intentar transferir la propiedad
En un nivel alto, esto es contra la corriente para Rust.
No puede transferir la propiedad de algo prestado
porque no lo posee
.
¡No debe pedir prestado mi auto (
&Car
) y luego dárselo a la primera persona que vea en la calle!
Esto sigue siendo cierto incluso si le presto mi automóvil y le permito hacer cambios en él (
&mut Car
).
No puede mover la
head
fuera de
&self
en absoluto porque no puede mutar el valor.
No puede mover la
head
fuera de
&mut self
porque esto dejaría la estructura
LinkedList
en un estado inconsistente; uno de los campos tendría un valor indefinido.
Esta es una medida central de las garantías de seguridad de Rust.
En general, deberá seguir algo de ¿Cómo puedo cambiar un nuevo valor para un campo en una referencia mutable a una estructura? para reemplazar el valor existente.
En este caso, puede usar
Option::take
.
Esto dejará la variable donde está, cambiándola in situ a
None
y devolviendo el valor anterior.
Luego puede usar ese valor para construir el nuevo encabezado de la lista:
pub fn prepend_value(&mut self) {
let head = self.head.take();
self.head = Some(Box::new(LinkedListNode { next: head }));
}
Una solución más genérica es tomar posesión de la estructura en lugar de tomarla prestada. Esto le permite hacer lo que quiera. Tenga en cuenta que tomamos por valor propio, no por referencia:
pub fn prepend_value(mut self) -> LinkedList {
self.head = Some(Box::new(LinkedListNode { next: self.head }));
self
}
Estoy escribiendo una lista vinculada para comprender las vidas, la propiedad y las referencias de Rust. Tengo el siguiente código:
pub struct LinkedList {
head: Option<Box<LinkedListNode>>,
}
pub struct LinkedListNode {
next: Option<Box<LinkedListNode>>,
}
impl LinkedList {
pub fn new() -> LinkedList {
LinkedList { head: None }
}
pub fn prepend_value(&mut self) {
let mut new_node = LinkedListNode { next: None };
match self.head {
Some(ref head) => new_node.next = Some(*head),
None => new_node.next = None,
};
self.head = Some(Box::new(new_node));
}
}
fn main() {}
Pero recibo el siguiente error de compilación:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:18:52
|
18 | Some(ref head) => new_node.next = Some(*head),
| ^^^^^ cannot move out of borrowed content
Las versiones más recientes de Rust tienen un error ligeramente diferente:
error[E0507]: cannot move out of `*head` which is behind a shared reference
--> src/main.rs:18:52
|
18 | Some(ref head) => new_node.next = Some(*head),
| ^^^^^ move occurs because `*head` has type `std::boxed::Box<LinkedListNode>`, which does not implement the `Copy` trait
Estoy pensando que el nodo principal debe ser propiedad de
self
, que es la lista vinculada.
Cuando lo asigno a
new_node.next
, probablemente se produzca un cambio de propiedad.
Preferiría no clonar el valor si es posible, ya que parece un desperdicio. No quiero simplemente "pedirlo prestado" durante la duración de la función. Realmente quiero transferir su propiedad.
¿Cómo puedo hacer eso?
Ya he visto que no se puede mover fuera del contenido prestado al desenvolver una variable miembro en un método mut y no se puede mover fuera del contenido prestado / no se puede mover detrás de una referencia compartida .
Intenté eliminar el brazo de coincidencia como se sugirió en la respuesta aceptada en una de esas preguntas y definir el
next
en la creación del nuevo
LinkedListNode
, pero recibo el mismo mensaje de error.
He agregado con éxito un método de
append
que toma un
LinkedListNode
para agregar al final de la lista.