133 votes

Que sont les durées de vie non lexicales?

La rouille a une RFC liées à la non-lexicale des durées de vie qui a été approuvé pour être mis en œuvre dans la langue pendant une longue période. Récemment, la Rouille de l'appui de cette fonction a beaucoup évolué et est considérée comme complète.

Ma question est: quel est exactement un non-lexicale vie?

213voto

Shepmaster Points 1732

Il est plus facile de comprendre ce que les non-lexicale des durées de vie sont par la compréhension de ce lexicale des durées de vie sont. Dans les versions de la Rouille avant de non-lexicale des durées de vie sont présents, ce code ne fonctionne pas:

fn main() {
    let mut scores = vec![1, 2, 3];
    let score = &scores[0];
    scores.push(4);
}

La Rouille compilateur voit qu' scores est emprunté par l' score variable, de sorte qu'il n'autorise pas une mutation de l' scores:

error[E0502]: cannot borrow `scores` as mutable because it is also borrowed as immutable
 --> src/main.rs:4:5
  |
3 |     let score = &scores[0];
  |                  ------ immutable borrow occurs here
4 |     scores.push(4);
  |     ^^^^^^ mutable borrow occurs here
5 | }
  | - immutable borrow ends here

Cependant, l'homme peut trivialement voir que cet exemple est trop prudente: score est jamais utilisé! Le problème est que l'emprunt d' scores par score est lexicales - elle dure jusqu'à la fin du bloc dans lequel elle est contenue:

fn main() {
    let mut scores = vec![1, 2, 3]; //
    let score = &scores[0];         //
    scores.push(4);                 //
                                    // <-- score stops borrowing here
}

Non-lexicale des durées de vie de résoudre ce problème en améliorant le compilateur de comprendre ce niveau de détail. Le compilateur ne peut désormais plus dire avec exactitude quand un emprunter est nécessaire et que ce code compile.

Une chose merveilleuse au sujet de la non-lexical de la durée de vie est que, une fois activé, vous ne serez jamais penser à eux. Il va tout simplement devenir "ce que la Rouille ne", et les choses vont (je l'espère), tout fonctionne.

Pourquoi n'ont-lexicale des durées de vie de permis?

La rouille est destiné à permettre connu programmes de sécurité pour les compiler. Cependant, il est impossible pour exactement autoriser uniquement les programmes de sécurité et de rejeter dangereux ceux. À cette fin, la Rouille se trompe sur le côté de conservatisme: certains programmes de sécurité sont rejetés. Lexicale des durées de vie sont un exemple.

Lexicale de durée de vie beaucoup plus facile à mettre en œuvre dans le compilateur parce que la connaissance de blocs est "trivial", tandis que la connaissance du flux de données est moins. Le compilateur a besoin d'être réécrit afin d'introduire et de faire usage d'un "mi-niveau intermédiaire de la représentation" (MIR). Alors l'emprunter checker (un.k.un. "borrowck") a dû être réécrit pour utiliser MIR au lieu de l'arbre de syntaxe abstraite (AST). Ensuite, les règles de l'emprunter vérificateur devait être affinée pour être plus fine granularité.

Lexicale des durées de vie ne sont pas toujours d'obtenir de la manière de le programmeur, et il y a beaucoup de façons de travailler autour lexical de la durée de vie quand ils le font, même s'ils sont ennuyeux. Dans de nombreux cas, il s'agissait de ajoutant des accolades ou une valeur booléenne. Cela a permis à la Rouille 1.0 de navire et être utile pour de nombreuses années avant que les non-lexicale des durées de vie ont été mises en œuvre.

Fait intéressant, certains bons modèles ont été développés en raison de lexique des durées de vie. Le meilleur exemple pour moi est l' entry modèle. Ce code ne fonctionne pas avant de non-lexicale des durées de vie et compile avec elle:

fn example(mut map: HashMap<i32, i32>, key: i32) {
    match map.get_mut(&key) {
        Some(value) => *value += 1,
        None => {
            map.insert(key, 1);
        }
    }
}

Cependant, ce code est inefficace parce qu'elle calcule le hachage de la clé deux fois. La solution qui a été créé parce que d'lexical de la durée de vie est plus courte et plus efficace:

fn example(mut map: HashMap<i32, i32>, key: i32) {
    *map.entry(key).or_insert(0) += 1;
}

Le nom de "non-lexicale des durées de vie" ne sonne pas le droit de me

La durée de vie d'une valeur est le laps de temps pendant lequel la valeur reste à une adresse de mémoire (voir Pourquoi je ne peux pas stocker une valeur et une référence à cette valeur dans la même structure? pour une explication plus longue). La fonctionnalité connue sous le nom de non-lexical de la durée de vie n'a pas de changement à la durée de vie de toutes les valeurs, de sorte qu'il ne peut pas faire de durée de vie non-lexicale. Il ne fait que le suivi et le contrôle de l'emprunte de ces valeurs plus précises.

Plus de précision le nom de la fonction peut être "non-lexicale emprunte". Certains les développeurs de compilateurs reportez-vous à la sous-jacentes "MIR à base de borrowck".

Non-lexical de la durée de vie n'a jamais été destiné à être un "utilisateur face" fonctionnalité, en soi. Ils ont surtout développé dans nos esprits, parce que du peu de papercuts nous obtenons de leur absence. Leur nom a été principalement destiné à l'interne à des fins de développement et de modification à des fins de marketing n'a jamais été une priorité.

Ouais, mais comment puis-je l'utiliser?

Dans la Rouille 1.31 (sorti sur 2018-12-06), vous devez opter pour la Rouille 2018 édition de votre Cargaison.toml:

[package]
name = "foo"
version = "0.0.1"
authors = ["An Devloper <an.devloper@example.com>"]
edition = "2018"

Comme de la Rouille 1.36, la Rouille 2015 edition permet aussi de non-lexicale des durées de vie.

L'implémentation actuelle de non-lexical de la durée de vie est dans un "mode de migration". Si la LLN emprunter le vérificateur de passe, la compilation continue. Si ça ne marche pas, la précédente emprunter checker est invoquée. Si l'ancien emprunter permet de checker le code, un message d'avertissement est affiché, vous informant que votre code est susceptible de briser dans une future version de Rouille et devrait être mis à jour.

Dans la nuit versions de Rouille, vous pouvez opter pour la disparition forcée de rupture par l'intermédiaire d'une fonction de drapeau:

#![feature(nll)]

Vous pouvez même opter pour la version expérimentale de LLN en utilisant le compilateur drapeau -Z polonius.

Un échantillon de réels problèmes sont résolus par des non-lexicale des durées de vie

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X