visual studio servers online microsoft lista español descargar community rust

studio - ¿Cómo sabe el compilador Rust si un valor se ha movido o no?



visual studio community (1)

Un simple ejemplo:

struct A; fn main() { test(2); test(1); } fn test(i: i32) { println!("test"); let a = A; if i == 2 { us(a); } println!("end"); } impl Drop for A { fn drop(&mut self) { println!("drop"); } } #[allow(unused_variables)] fn us(a: A){ println!("use"); }

Cuando lo ejecuto, la salida es:

test use drop end test end drop

Entiendo que en el caso de la test(2) , a se mueve a us(a) , por lo que su salida es "uso de prueba-finalización".

Sin embargo, en la test(1) , el resultado es "test-end-drop", lo que significa que el compilador sabe que a no se movió.

Si se llama a us(a) , no será necesario ingresar a test(i) , se eliminará en us(a) ; y si us(a) no se llama, se debe descartar después de println!("end") .

Dado que es imposible para el compilador saber si a.drop() o no, ¿cómo sabe el compilador si se llamará o no a.drop() después de println!("end") ?


Esto se explica en el Rustnomicon :

A partir de Rust 1.0, los marcadores de soltar en realidad no están ocultos en secreto en un campo oculto de cualquier tipo que implemente Drop.

El campo oculto indica si el valor actual se ha eliminado o no, y si no lo ha sido, entonces sí lo está. Por lo tanto, esto se conoce en tiempo de ejecución y requiere un poco de contabilidad.

Mirando hacia el futuro, hay un RFC para eliminar estos campos ocultos .

La idea del RFC es reemplazar los campos ocultos por:

  1. Identificar caídas incondicionales (que no necesitan ningún control en tiempo de ejecución)
  2. Oculta un campo oculto en la pila , en el marco de la función, para esos valores que se eliminan condicionalmente

Esta nueva estrategia tiene varias ventajas sobre la anterior:

  • la principal ventaja es que #[repr(C)] ahora siempre dará una representación equivalente a la de C incluso si la struct implementa Drop
  • Otra ventaja importante es el ahorro de memoria (al NO inflar el tamaño de la struct )
  • Otra ligera ventaja es una posible ligera ganancia de velocidad debido a caídas incondicionales y mejor almacenamiento en caché (a partir de la reducción del tamaño de la memoria)