rust rust-obsolete

rust - ¿Por qué “se requiere límite de vida explícito” para el recuadro<T> en la estructura?



rust-obsolete (2)

(Punto ligeramente pedante: que A es un rasgo, por lo que S no posee una instancia de A , es propietario de una instancia en caja de algún tipo que implementa A ).

Un objeto de rasgo representa datos con algún tipo desconocido, es decir, lo único que se sabe acerca de los datos es que implementa el rasgo A Debido a que el tipo no se conoce, el compilador no puede razonar directamente sobre la vida útil de los datos contenidos, por lo que requiere que esta información se indique explícitamente en el tipo de objeto de rasgo.

Esto se hace a través de Trait+''lifetime . La ruta más fácil es simplemente usar ''static , es decir, no permitir el almacenamiento de datos que pueden quedar inválidos debido a los ámbitos:

a: Box<A + ''static>

Anteriormente, (antes de que se introdujera la posibilidad de objetos de rasgos limitados por la vida y este mensaje de error explicit lifetime bound required ) todos los objetos de los rasgos en caja estaban implícitamente ''static , es decir, esta forma restringida era la única opción.

La forma más flexible es exponer el tiempo de vida externamente:

struct S<''x> { a: Box<A + ''x> }

Esto permite que S almacene un objeto de rasgo de cualquier tipo que implemente A , posiblemente con algunas restricciones en los ámbitos en los que la S es válida (es decir, para los tipos en los que ''x es menor que ''static el objeto S quedará atrapado dentro de una pila cuadro).

Nota del editor: este código ya no produce el mismo error después de que se implementó RFC 599 , pero los conceptos analizados en las respuestas siguen siendo válidos.

Estoy tratando de compilar este código:

trait A { fn f(&self); } struct S { a: Box<A>, }

y estoy recibiendo este error:

a.rs:6:13: 6:14 error: explicit lifetime bound required a.rs:6 a: Box<A>,

Quiero que Sa posea una instancia de A , y no veo cómo es apropiada esa vida aquí. ¿Qué necesito hacer para hacer feliz al compilador?

Mi versión Rust:

rustc --version rustc 0.12.0-pre-nightly (79a5448f4 2014-09-13 20:36:02 +0000)


El problema aquí es que también se puede implementar un rasgo para referencias, por lo que si no especifica la vida útil requerida para Box, cualquier cosa podría almacenarse allí.

Puede ver sobre los requisitos de por vida en este rfc .

Entonces, una posible solución es vincular la vida útil, entonces Send (ponemos I en S):

trait A { fn f(&self); } struct I; impl A for I { fn f(&self) { println!("A for I") } } struct S { a: Box<A + Send> } fn main() { let s = S { a: box I }; s.a.f(); }

El otro es configurar la vida útil a ''a (podemos poner una referencia y I o I a S):

trait A { fn f(&self); } struct I; impl A for I { fn f(&self) { println!("A for I") } } impl <''a> A for &''a I { fn f(&self) { println!("A for &I") } } struct S<''a> { a: Box<A + ''a> } fn main() { let s = S { a: box &I }; s.a.f(); }

Tenga en cuenta que esto es más general y podemos almacenar tanto las referencias como los datos de propiedad (tipo de Send que tiene una vida útil de ''static ) pero requiere un parámetro de vida útil en todas partes donde se usa el tipo.