metafora longitud juridica ejemplos description caracteres types rust traits

types - juridica - longitud title seo



Definición de tipo con un rasgo: diferencias de especificar un límite de vida explícito? (1)

Responda por una nueva pregunta

Realmente tienes dos casos ortogonales. Primero abordaré el más fácil, la diferencia de # 2 y # 3. Los comentarios están en línea con lo que espero sea un ejemplo representativo:

trait Kind { fn trait_fn(&self) -> u8 { 0 } } type CollectionOfKind1<''a> = Vec<&''a (Kind + ''static)>; type CollectionOfKind2<''a> = Vec<&''a (Kind + ''a)>; struct Alpha; impl Kind for Alpha {} struct Beta<''b> { name: &''b str, } impl<''a> Kind for Beta<''a> {} fn main() { let name = "world".to_string(); // Doesn''t need/have it''s own lifetime. let a = Alpha; // Has a reference to something with the ''static lifetime. let b1 = Beta { name: "hello" }; // Has a reference to something with the lifetime of `name`, // which is less than ''static. let b2 = Beta { name: &name[..] }; // Our vector is composed of references to // things that *might* have a reference themselves! let mut c1: CollectionOfKind1 = Vec::new(); c1.push(&a); c1.push(&b1); // c1.push(&b2); // error: `name` does not live long enough let mut c2: CollectionOfKind2 = Vec::new(); c2.push(&a); c2.push(&b1); c2.push(&b2); // Hooray }

Es de destacar que las vidas no tienen que ser las mismas . Podrías haber escrito:

type CollectionOfKind2<''a, ''b> = Vec<&''a (Kind + ''b)>;

La segunda cosa es el significado del trait Foo : ''static . Estoy menos seguro aquí, pero escribí este pequeño ejemplo:

trait Foo : ''static {} fn x(a: &Foo) {} fn main() { x(&3u8); }

Este error durante la compilación con

el rasgo Foo debe implementar para el elenco al tipo de objeto Foo + ''static

Basado en eso, creo que Foo : ''static es solo otra forma de escribir Foo + ''static . La principal diferencia que puedo pensar es que restringe el rasgo para que nunca se implemente en una estructura con tiempos de vida no ''static :

struct B<''a> { b: &''a str, } impl<''a> Foo for B<''a> {}

Tiene el error

el tiempo de vida declarado no está satisfecho, [...] pero el parámetro de por vida debe sobrevivir a la vida útil estática

Respuesta original

Veo que ya descubrió esto, pero es posible que desee actualizar su versión de Rust. Si compilo tu código en el Playpen, recibo una sugerencia sobre cómo solucionarlo:

error: expected a path on the left-hand side of `+`, not `&''a Kind` [E0178] type CollectionOfKind<''a> = Vec<&''a Kind + ''a>; ^~~~~~~~ note: perhaps you meant `&''a (Kind + ''a)`? (per RFC 438) type CollectionOfKind<''a> = Vec<&''a Kind + ''a>; ^~~~~~~~

Eso hace referencia a RFC 438, Precedence of Plus .

Tengo problemas para comprender los requisitos de límite de por vida cuando uso un rasgo en una definición de tipo. Por ejemplo:

trait Kind { /* ... */ } type CollectionOfKind<''a> = Vec<&''a Kind>; // => error: explicit lifetime bound required

El requisito de límites de por vida ya se ha discutido para el caso de un rasgo dentro de una estructura ( Respuesta 1 , Respuesta 2 ). Al principio, tuve problemas para aplicar el enfoque de "agregar vida útil" aquí en absoluto, ya que esto no funciona:

type CollectionOfKind<''a> = Vec<&''a Kind + ''a>; type CollectionOfKind<''a> = Vec<&''a Kind + ''static>;

Sin embargo, esto fue solo un problema de sintaxis, debido a la precedencia de más como lo señala @Shepmaster.

En general, ahora he encontrado tres formas de especificar los límites de por vida:

// Version 1: Adding ''static to the trait itself trait Kind : ''static { /* ... */ } type CollectionOfKind<''a> = Vec<&''a Kind>;

// Version 2: Adding ''static to the type definition trait Kind { /* ... */ } type CollectionOfKind<''a> = Vec<&''a (Kind + ''static)>;

// Version 3: Adding the lifetime of the reference to the trait object (?) trait Kind { /* ... */ } type CollectionOfKind<''a> = Vec<&''a (Kind + ''a)>;

Lo que no entiendo: ¿Cuál es la diferencia exacta entre estos tres casos?

Mis problemas:

Para ver las diferencias, estaba tratando de comprender ciertos puntos mencionados en las otras respuestas. Por ejemplo, en la respuesta 2 vinculada anteriormente, he encontrado la siguiente pista que no entiendo completamente:

En este caso, el ''static requiere que el objeto subyacente sea una estructura real, o una &''static referencia &''static , pero no se permitirán otras referencias.

¿Qué significa que el objeto subyacente debe ser una estructura "real"? ¿Cómo es posible que una estructura implemente el rasgo sin ser "real"?

Del mismo modo para la cita que @Shepmaster ha citado:

Debe especificar la duración dos veces: una para la duración de la referencia y otra para el objeto de rasgo en sí, porque los rasgos pueden implementarse para referencias, y si el objeto subyacente es una referencia, también debe especificar su duración.

Para ser sincero, no veo por qué debe especificarse dos veces. Pensé que un objeto de rasgo se define por ser una referencia a un objeto que implementa un rasgo determinado. Por lo tanto, es por definición (?) Una referencia, y por lo tanto, tiene una vida de todos modos?