Recherche…


Syntaxe

  • Fonction fn <'a> (x: &' a Type)
  • struct Struct <'a> {x: &' a Type}
  • enum Enum <'a> {Variante (&' un Type)}
  • impl <'a> Struct <' a> {fn x <'a> (& self) -> &' a Type {self.x}}
  • impliquer <'a> Trait <' a> pour le type
  • impliquer <'a> Trait pour le type <' a>
  • fn function<F>(f: F) where for<'a> F: FnOnce(&'a Type)
  • struct Struct<F> where for<'a> F: FnOnce(&'a Type) { x: F }
  • enum Enum<F> where for<'a> F: FnOnce(&'a Type) { Variant(F) }
  • impl<F> Struct<F> where for<'a> F: FnOnce(&'a Type) { fn x(&self) -> &F { &self.x } }

Remarques

  • Toutes les références dans Rust ont une durée de vie, même si elles ne sont pas explicitement annotées. Le compilateur est capable d'affecter implicitement des durées de vie.
  • La 'static durée de vie 'static est assignée aux références stockées dans le programme binaire et sera valide pendant toute son exécution. Cette durée de vie est plus particulièrement affectée aux littéraux de chaîne, qui ont le type &'static str .

Paramètres de fonction (durée de vie des entrées)

fn foo<'a>(x: &'a u32) {
    // ...
}

Cela spécifie que foo a la durée 'a vie 'a et que le paramètre x doit avoir une durée de vie d'au moins 'a . Les durées de vie des fonctions sont généralement omises lors de l' élision à vie :

fn foo(x: &u32) {
    // ...
}

Dans le cas où une fonction prend plusieurs références en tant que paramètres et renvoie une référence, le compilateur ne peut pas déduire la durée de vie du résultat au cours de la durée de vie .

error[E0106]: missing lifetime specifier
1 | fn foo(bar: &str, baz: &str) -> &i32 {
  |                                 ^ expected lifetime parameter

Au lieu de cela, les paramètres de durée de vie doivent être explicitement spécifiés.

// Return value of `foo` is valid as long as `bar` and `baz` are alive.
fn foo<'a>(bar: &'a str, baz: &'a str) -> &'a i32 {

Les fonctions peuvent également prendre plusieurs paramètres de durée de vie.

// Return value is valid for the scope of `bar`
fn foo<'a, 'b>(bar: &'a str, baz: &'b str) -> &'a i32 {

Champs Struct

struct Struct<'a> {
    x: &'a u32,
}

Cela spécifie que toute instance donnée de Struct a la durée 'a vie 'a et que le &u32 stocké dans x doit avoir une durée de vie d'au moins 'a .

Blocs d'implants

impl<'a> Type<'a> {
    fn my_function(&self) -> &'a u32 {
        self.x
    }
}

Cela spécifie que Type a la durée 'a vie 'a et que la référence renvoyée par my_function() peut ne plus être valide après 'a ends car le Type n'existe plus pour contenir self.x

Limites de trait de rang supérieur

fn copy_if<F>(slice: &[i32], pred: F) -> Vec<i32>
    where for<'a> F: Fn(&'a i32) -> bool
{
    let mut result = vec![];
    for &element in slice {
        if pred(&element) {
            result.push(element);
        }
    }
    result
}

Cela spécifie que la référence sur i32 dans le trait Fn lié peut avoir n'importe quelle durée de vie.

Les éléments suivants ne fonctionnent pas:

fn wrong_copy_if<'a, F>(slice: &[i32], pred: F) -> Vec<i32>
    where F: Fn(&'a i32) -> bool
{                                   // <----------------+
    let mut result = vec![];        //       'a scope   |
    for &element in slice {         // <--------+       |
        if pred(&element) {         //          |       |
            result.push(element);   // element's|       |
        }                           //   scope  |       |
    }                               // <--------+       |
    result                          //                  |
}                                   // <----------------+

Le compilateur donne l'erreur suivante:

error: `element` does not live long enough
if pred(&element) {         //          |       |
         ^~~~~~~

parce que l' element variable locale ne vit pas aussi longtemps que la 'a vie (comme on peut le voir dans les commentaires du code).

La durée de vie ne peut pas être déclarée au niveau de la fonction, car nous avons besoin d'une autre durée de vie. C'est pourquoi nous avons utilisé for<'a> : pour spécifier que la référence peut être valide pour n'importe quelle durée de vie (une durée de vie plus courte peut donc être utilisée).

Les limites de trait de rang supérieur peuvent également être utilisées sur des structures:

struct Window<F>
    where for<'a> F: FnOnce(&'a Window<F>)
{
    on_close: F,
}

ainsi que sur d'autres articles.

Les limites de trait de rang supérieur sont les plus couramment utilisées avec les traits Fn* .

Pour ces exemples, l'élision à vie fonctionne bien, nous n'avons donc pas à spécifier les durées de vie.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow