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.