traduccion ps4 lenguaje language descargar reference rust move-semantics borrow-checker

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.