rust lifetime

rust - ¿Por qué es necesario agregar una vida útil a un rasgo con el operador más(Iterator<Item=& Foo>+''a)?



lifetime (1)

Estoy aplicando un cierre en el iterador y quiero usar estable, por lo que quiero devolver un Iterator caja. La forma obvia de hacerlo es la siguiente:

struct Foo; fn into_iterator(myvec: &Vec<Foo>) -> Box<Iterator<Item = &Foo>> { Box::new(myvec.iter()) }

Esto falla porque el verificador de préstamos no puede inferir las vidas apropiadas.

Después de investigar un poco, ¿he encontrado la forma correcta de devolver un iterador? , lo que me llevó a agregar + ''a :

fn into_iterator<''a>(myvec: &''a Vec<Foo>) -> Box<Iterator<Item = &''a Foo> + ''a> { Box::new(myvec.iter()) }

Pero no entiendo

  • Que hace esto
  • Y por qué se necesita aquí

Hay una cosa que se pasa por alto fácilmente: si tiene un rasgo Foo y desea tener un objeto de rasgo en caja Box<Foo> , el compilador agrega automáticamente un ''static límite de vida ''static (como se especifica en RFC 599 ). ¡Esto significa que Box<Foo> y Box<Foo + ''static> son equivalentes!

En su caso, el compilador agrega automáticamente el límite estático de modo que esto ...

fn into_iterator(myvec: &Vec<Foo>) -> Box<Iterator<Item = &Foo>>

... es equivalente a eso:

fn into_iterator(myvec: &Vec<Foo>) -> Box<Iterator<Item = &Foo> + ''static>

Ahora, las reglas de elisión de por vida entran y "conectan" las dos ranuras de por vida, de modo que el código anterior es equivalente a:

fn into_iterator<''a>(myvec: &''a Vec<Foo>) -> Box<Iterator<Item = &''a Foo> + ''static>

¡Pero el tipo Iter<''a, Foo> (el tipo de iterador específico para Vec<Foo> ) obviamente no satisface el límite ''static (porque está tomando prestado el Vec<Foo> )! Entonces tenemos que decirle al compilador que no queremos el ''static enlace ''static predeterminado al especificar nuestro propio enlace de por vida:

fn into_iterator<''a>(myvec: &''a Vec<Foo>) -> Box<Iterator<Item = &Foo> + ''a>

Ahora el compilador sabe que el objeto rasgo solo es válido para toda la vida ''a . ¡Tenga en cuenta que no necesitamos anotar explícitamente la vida útil del tipo de Item asociado! Las reglas de elisión de por vida se encargan de eso.