es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Qué significa una duración de vida estática de un tipo de cierre Fn?

El siguiente error desaparece si hago lo que me indica rustc y cambio el límite a:

where F: Fn() -> () + 'static
pub struct Struct(Box<dyn Fn() -> ()>);
pub fn example<F>(f: F)
where
    F: Fn() -> ()
{
    Struct(Box::new(|| ())); // ok
    Struct(Box::new(f)); // error: El tipo del parámetro `F` puede que no viva el tiempo suficiente
                         // ayuda: considere agregar un límite de tiempo de vida explícito: `F: 'static`
}

Sin embargo, simplemente no entiendo lo que significa 'static aquí. No parece que se refiera a que la clausura misma vive para siempre.

Al menos, no parece que la clausura viva para siempre. Si la clausura posee algunos datos, esos datos se descartan en algún momento, lo que me hace sospechar que la clausura se descarta:

pub struct Struct(Box<dyn Fn() -> ()>);

#[derive(Debug)]
struct DropMe;
impl Drop for DropMe {
    fn drop(&mut self) {
        println!("descartado");
    }
}

/// imprime:
///     "obtenido DropMe"
///     "obtenido DropMe"
///     "descartado"
///     "fin del programa"
pub fn main() {
    let d = DropMe;
    example(move || {
        println!("obtenido {:?}", d);
    });
    println!("fin del programa")
}

pub fn example<F>(f: F)
where
    F: Fn() -> () + 'static
{
    let s = Struct(Box::new(f));
    s.0();
    s.0();
}

¿Es 'static un límite superior en el tiempo de vida de la clausura en lugar de un límite inferior? 'static tiene sentido como un límite superior, luego example diría “dame una función que pueda mantener todo el tiempo que quiera”, lo cual en la práctica puede ser menor que el tiempo de vida 'static.

¿Cómo puedo saber cuándo + 'lifetime agrega 'lifetime como un límite superior o inferior?
El capítulo del Rustonomicon sobre subtipos+varianza no parece cubrir esto, y no pude encontrar la información que estaba buscando en el Libro de Rust o en la Referencia de Rust.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Entendiendo el significado de 'static en Rust

    En el código Rust proporcionado, el mensaje de error sugiere agregar una restricción de tiempo de vida de F: 'static, lo cual puede resultar confuso ya que no parece significar que la clausura en sí misma vive para siempre. Sin embargo, 'static no se refiere al tiempo de vida de la clausura o los datos que captura, sino al tiempo de vida mínimo del puntero a función F en sí.

    Por lo tanto, agregar la restricción 'static a la firma de la función example significa que cualquier implementación de F debe ser válida y vivir durante toda la duración del programa. Esto significa que el puntero a función no tiene ningún tiempo de vida asociado y, por lo tanto, se puede mantener de manera segura en cualquier punto de la ejecución del programa.

    En otras palabras, 'static actúa como una restricción superior para el tiempo de vida de F, asegurando que el puntero a función permanezca válido mientras se ejecute el programa.

    Entendiendo el impacto de + 'lifetime en restricciones de tiempo de vida

    Cuando se agrega un tiempo de vida 'lifetime usando la sintaxis +, se modifica las restricciones de tiempo de vida existentes al agregar una restricción adicional.

    Si un tipo T tiene una restricción de tiempo de vida &'a T, y especificamos una restricción de tiempo de vida + 'b, esto significa que T ahora debe cumplir el requisito de que 'a: 'b, además de la restricción original de &'a T. En esencia, esto agrega 'b como una restricción inferior para el tiempo de vida de T.

    De manera similar, si agregamos una restricción de tiempo de vida 'b a un tipo T que ya tiene una restricción de tiempo de vida &'a T, la nueva restricción de &'a T + 'b agrega 'b como una restricción superior para el tiempo de vida de T.

    Por lo tanto, cuando se agrega una restricción de F: Fn() -> () + 'static a la firma de una función, significa que cualquier implementación de F debe cumplir el requisito de que el tiempo de vida del puntero a función debe ser al menos 'static (es decir, vivir durante toda la duración del programa), además de implementar el trait Fn() -> ().

Comments are closed.