IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Communiqués de presse

    Homme Profil pro
    Rédacteur technique
    Inscrit en
    Avril 2025
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Rédacteur technique

    Informations forums :
    Inscription : Avril 2025
    Messages : 721
    Par défaut Rust 1.92 active les tables de déroulement par défaut et affine les vérifications de lints et d'attributs
    La version 1.92 du langage de programmation Rust est disponible, introduisant les tables de déroulement par défaut et affinant les vérifications de lints et d'attributs

    Rust 1.92 est la dernière version du langage de programmation polyvalent, qui introduit des changements importants pour les développeurs. Notamment, les tables de déroulement sont désormais émises par défaut même lorsque le drapeau -Cpanic=abort est activé, ce qui garantit le bon fonctionnement des traces de retour en arrière dans les scénarios de panique-abandon. Les utilisateurs qui ne souhaitent pas utiliser les tables de déroulement peuvent désormais les désactiver explicitement avec -Cforce-unwind-tables=no.

    Rust est un langage de programmation compilé multi-paradigme qui met l'accent sur la performance, la sûreté des types et la concurrence. Il assure la sécurité mémoire, ce qui signifie que toutes les références pointent vers une mémoire valide, sans nécessiter l'utilisation de techniques de gestion de la mémoire automatisée telles que le ramasse-miettes. Afin d'assurer la sécurité de la mémoire et d'empêcher une situation de compétition aux données, son « vérificateur d'emprunts » suit la durée de vie des objets de toutes les références dans un programme à la compilation. Rust a été remarqué pour son adoption rapide, selon le Stack Overflow Survey 2025, c'est le langage le plus apprécié dans ce sondage.

    Rust 1.92 est la dernière version du langage de programmation polyvalent, qui introduit des changements importants pour les développeurs. Notamment, les tables de déroulement sont désormais émises par défaut même lorsque le drapeau -Cpanic=abort est activé, ce qui garantit le bon fonctionnement des traces de retour en arrière dans les scénarios de panique-abandon. Les utilisateurs qui ne souhaitent pas utiliser les tables de déroulement peuvent désormais les désactiver explicitement avec -Cforce-unwind-tables=no.

    Suite aux améliorations continues apportées au système de types, cette version poursuit les efforts de stabilisation du type never. Deux futurs lints de compatibilité, never_type_fallback_flowing_into_unsafe et dependency_on_unit_never_type_fallback, sont désormais refusés par défaut, ce qui signifie que toute violation entraînera des erreurs de compilation plutôt que des avertissements ou une autorisation silencieuse.

    En ce qui concerne les lints, le lint unused_must_use n'émet plus d'avertissement lorsque les fonctions renvoient un Result ou un ControlFlow, tel que Result. Cela reflète le fait que ces types d'erreurs ne peuvent pas réellement se produire, ce qui réduit les vérifications inutiles pendant le développement.

    Ces mises à jour fondamentales s'accompagnent de modifications importantes dans la gestion des attributs intégrés à Rust. Le compilateur traite désormais les attributs de manière plus stricte et génère des diagnostics plus clairs et plus cohérents. Par exemple, les arguments macro_export incorrects dans les dépendances sont désormais considérés comme des lints refusés par défaut, ce qui rend ces problèmes plus visibles lors de la compilation.

    Nom : 1.jpg
Affichages : 21724
Taille : 18,4 Ko

    Voici les principales mises à jour de la version 1.92.0 :

    Lignes de code never type refusées par défaut

    Les équipes chargées du langage et du compilateur continuent de travailler à la stabilisation du type never. Dans cette version, les lignes de code never_type_fallback_flowing_into_unsafe et dependency_on_unit_never_type_fallback, compatibles avec les versions futures, ont été refusées par défaut, ce qui signifie qu'elles provoqueront une erreur de compilation lorsqu'elles seront détectées.

    Il convient de noter que même si cela peut entraîner des erreurs de compilation, il s'agit toujours d'un lint ; ces lints peuvent tous être #[allow]. Ces lints ne se déclencheront également que lors de la compilation directe des crates concernées, et non lorsqu'elles sont compilées en tant que dépendances (bien qu'un avertissement soit signalé par Cargo dans de tels cas).

    Ces lints détectent le code susceptible d'être rompu par la stabilisation du type never. Il est fortement recommandé de les corriger s'ils sont signalés dans votre graphique de crate.

    Nous estimons qu'environ 500 crates sont concernées par ce lint. Malgré cela, nous pensons que cela est acceptable, car les lints ne constituent pas un changement radical et permettront de stabiliser le type never à l'avenir.


    unused_must_use n'affiche plus d'avertissement concernant Result<(), UninhabitedType>

    Le lint unused_must_use de Rust affiche un avertissement lorsque la valeur de retour d'une fonction est ignorée, si la fonction ou son type de retour est annoté avec #[must_use]. Par exemple, cela avertit si vous ignorez un type de retour de Result, pour vous rappeler d'utiliser ?, ou quelque chose comme .expect(« ... »).

    Cependant, certaines fonctions renvoient Result, mais le type d'erreur qu'elles utilisent n'est en fait pas « habité », ce qui signifie que vous ne pouvez construire aucune valeur de ce type (par exemple, les types ! ou Infallible).

    Le lint unused_must_use n'affiche désormais plus d'avertissement sur Result<(), UninhabitedType> ou sur ControlFlow<UninhabitedType, ()>. Par exemple, il n'affichera pas d'avertissement sur Result<(), Infallible>. Cela évite d'avoir à vérifier une erreur qui ne peut jamais se produire.

    Code Rust : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    use core::convert::Infallible;
    fn can_never_fail() -> Result<(), Infallible> {
        // ...
        Ok(())
    }
     
    fn main() {
        can_never_fail();
    }



    Ceci est particulièrement utile avec le modèle courant d'un trait associé à un type d'erreur, où le type d'erreur peut parfois être infaillible :

    Code Rust : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    trait UsesAssocErrorType {
        type Error;
        fn method(&self) -> Result<(), Self::Error>;
    }
     
    struct CannotFail;
    impl UsesAssocErrorType for CannotFail {
        type Error = core::convert::Infallible;
        fn method(&self) -> Result<(), Self::Error> {
            Ok(())
        }
    }
     
    struct CanFail;
    impl UsesAssocErrorType for CanFail {
        type Error = std::io::Error;
        fn method(&self) -> Result<(), Self::Error> {
            Err(std::io::Error::other("something went wrong"))
        }
    }
     
    fn main() {
        CannotFail.method(); // No warning
        CanFail.method(); // Warning: unused `Result` that must be used
    }



    Émettre des tables de déroulement même lorsque -Cpanic=abort est activé sous Linux

    Les backtraces avec -Cpanic=abort fonctionnaient auparavant dans Rust 1.22, mais ne fonctionnaient plus dans Rust 1.23, car nous avons cessé d'émettre des tables de déroulement avec -Cpanic=abort. Dans Rust 1.45, une solution de contournement sous la forme de -Cforce-unwind-tables=yes a été stabilisée.

    Dans Rust 1.92, les tables de déroulement seront émises par défaut même lorsque -Cpanic=abort est spécifié, ce qui permettra aux backtraces de fonctionner correctement. Si les tables de déroulement ne sont pas souhaitées, les utilisateurs doivent utiliser -Cforce-unwind-tables=no pour désactiver explicitement leur émission.

    Valider l'entrée vers #[macro_export]

    Au cours des dernières versions, de nombreux changements ont été apportés à la manière dont les attributs intégrés sont traités dans le compilateur. Cela devrait considérablement améliorer les messages d'erreur et les avertissements fournis par Rust pour les attributs intégrés et, surtout, rendre ces diagnostics plus cohérents parmi les plus de 100 attributs intégrés.

    Pour donner un petit exemple, dans cette version en particulier, Rust est devenu plus strict dans la vérification des arguments autorisés pour macro_export en mettant à niveau cette vérification vers un « lint par défaut refusé » qui sera signalé dans les dépendances.

    Source : Annonce Rust 1.92

    Et vous ?

    Pensez-vous que cette mise à jour est crédible ou pertinente ?
    Quel est votre avis sur le sujet ?

    Voir aussi :

    La version 1.91 du langage de programmation Rust est disponible, ajoutant la prise en charge de niveau 1 pour la plateforme Windows ARM64, les avertissements de pointeurs bruts, et plus encore

    La fondation Rust annonce la création d'un fonds pour les mainteneurs afin d'assurer la continuité et de soutenir les rôles à long terme des développeurs qui rendent possible le langage de programmation Rust

    C'est désormais officiel : Rust dans le noyau Linux sort du cadre expérimental. Le Rust vient de faire l'objet d'intégration comme partie essentielle du kernel aux côtés du toujours présent langage C
    Publication de communiqués de presse en informatique. Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

  2. #2
    Membre confirmé
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Mai 2015
    Messages
    670
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Mai 2015
    Messages : 670
    Par défaut Là j'ai du mal a comprendre...
    à tous,

    Je ne suis pas un expert en Rust, mais j'ai du mal a comprendre l'intérêt du type ! (never), que je viens de découvrir via le post précédent.

    De ce que je comprend, il est là pour "signaler" qu'une fonction ne retourne pas de valeur. Mais, pourquoi faut-il signaler au compilateur qu'une fonction ne retourne pas de valeur ? SI une fonction n'a pas a retourner de valeur, le compilateur pourrait le détecter car il n'y aurait dans ce cas pas de 'return' dans le code de la fonction ? (ou de yield dans le cas d'une coroutine).

    En pascal, on différence cela via une procédure (qui ne retourne pas de valeur), et une fonction qui elle retourne une valeur (je ne sais plus si elle DOIT ou si elle PEUT) retourner une valeur.

    De même, le compilateur pourrait refuser de compiler du code qui ne récupère pas la/les valeurs de retour, non ? N'a-t-il pas toutes les informations nécessaires pour le faire ?

    J'ai tenté quelques recherches, mais je n'ai pas été convaincu de son intérêt (ou, ce qui est fort possible, que je ne l'ai pas compris, soit parce que l'explication n'était pas clair, soit parce que l'explication était trop compliquée pour moi).

    Merci d'avance pour vos lumières.

    BàV et Peace & Love.

  3. #3
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 765
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 765
    Par défaut
    Citation Envoyé par OuftiBoy Voir le message
    De ce que je comprend, il est là pour "signaler" qu'une fonction ne retourne pas de valeur. Mais, pourquoi faut-il signaler au compilateur qu'une fonction ne retourne pas de valeur ? SI une fonction n'a pas a retourner de valeur, le compilateur pourrait le détecter car il n'y aurait dans ce cas pas de 'return' dans le code de la fonction ? (ou de yield dans le cas d'une coroutine).
    Une fonction qui retourne ! fait bien plus que ne pas retourner de valeur : elle indique explicitement qu'elle ne se terminera jamais, soit parce qu'elle boucle indéfiniment, soit parce qu'elle termine le fil d’exécution (panique ou exit). Le point d’exclamation n'est pas pour le moment un type a part entière (il n'est utilisable qu'en retour de fonction), mais le but est qu'il devienne le moyen standard de représenter un type qui ne peut exister. Actuellement on utilise pour ça les énumération vides qui partagent certains points commun, notamment le fait de ne pas pouvoir être instanciées.

    Ces types ont diverses particularités permises par le fait que leur utilisation concrète est impossible. Par exemple le type ! est automatiquement convertissable en n'importe quel autre type. Ca a de vrai usages sans qu'on s'en rende forcément compte.
    Le code suivant ne fonctionnerait pas si la macro panic qui interrompt l’exécution ne retournait pas !, car tous les éléments du match sont censés être du même type.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        let texte = match chiffre {
            1 => "un",
            2 => "deux",
            _ => panic!("nombre non supporté"),
        };
    Un autre particularité est que les variant d'une énumération contenant un type non instanciable ne sont pas utilisables non plus, donc qu'il n'y a pas besoin de les traiter dans les cas de pattern matching exhaustif:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        let nombre: Result<u32,!> = Ok(10);
        let Ok(x) = nombre;  // pas besoin de gérer le cas Err car le type `!` le rend impossible.

    Citation Envoyé par OuftiBoy Voir le message
    En pascal, on différence cela via une procédure (qui ne retourne pas de valeur), et une fonction qui elle retourne une valeur (je ne sais plus si elle DOIT ou si elle PEUT) retourner une valeur.
    En Rust comme en C, il n'y a pas de différenciation entre fonctions et procédures au niveau de la syntaxe, mais il y a bien des fonctions sans type de retour spécifié. En fait ces fonctions retournent implicitement le type unité : (). Ce type unité ne contient aucune valeur (il a une taille de zéro octets), mais il reste et instanciable, contrairement au type ! et aux énumération vides.

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2007
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Janvier 2007
    Messages : 257
    Par défaut
    En réalité ! signifie qu'à la fin de la function, le code ne va pas reprendre chez l'appelant.

    Un exemple est la fonction std::process::exit ( https://doc.rust-lang.org/std/process/fn.exit.html ) dont la signature est pub fn exit(code: i32) -> !

    Si tu as un code tel que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    fn main() {
        println!("hello");
        std::process::exit(0);
        println!("world");
    }
    World ne sera pas exécuté car la fonction exit ne reviendra jamais dans la fonction main.

    Cela permet de faciliter les analyse de code pour déterminer que le code suivant cette appel de function ne sera jamais exécuté.
    Ça permet également d'éviter de devoir faire un exit(0) suivi d'un return <quelque chose> si l'on veut quitter le programme directement depuis une fonction.

    Une fonction ne renvoyant pas de valeur fn ma_fonction() {} correspond en réalité à fn ma_fonction() -> () {}
    Dans ce cas, à la fin de l'exécution de cette fonction, le flux de code continuera à partir de la prochaine instruction dans la fonction appellante.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    fn main() {
        println!("hello");
        ma_fonction();
        println!("world");
    }
    Ici hello et world seront bien afficher dans la console.

    Désolé pour le formatage de mon message. Je n'ai pas trouvé comment faire sur téléphone.

  5. #5
    Membre confirmé
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Mai 2015
    Messages
    670
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Mai 2015
    Messages : 670
    Par défaut Merci, mais
    Citation Envoyé par gta126 Voir le message
    En réalité ! signifie qu'à la fin de la function, le code ne va pas reprendre chez l'appelant.

    Un exemple est la fonction std::process::exit ( https://doc.rust-lang.org/std/process/fn.exit.html ) dont la signature est pub fn exit(code: i32) -> !

    Si tu as un code tel que :
    fn main() {
    println!("hello");
    std::process::exit(0);
    println!("world");
    }

    World ne sera pas exécuté car la fonction exit ne reviendra jamais dans la fonction main.
    Ok, mais dans ce cas, pourquoi ne pas faire un simple 'return' ou 'exit'.

    c'est un peut comme si je fais en 'C'

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    fct() {
        code...
        return
        code...
    }
    Le compilateur peut détecter que ce qui se trouve après le 'return' ne sera pas exécuté, non ?

    Citation Envoyé par gta126 Voir le message
    Cela permet de faciliter les analyse de code pour déterminer que le code suivant cette appel de function ne sera jamais exécuté.
    Ça permet également d'éviter de devoir faire un exit(0) suivi d'un return <quelque chose> si l'on veut quitter le programme directement depuis une fonction.

    Une fonction ne renvoyant pas de valeur fn ma_fonction() {} correspond en réalité à fn ma_fonction() -> () {}
    Dans ce cas, à la fin de l'exécution de cette fonction, le flux de code continuera à partir de la prochaine instruction dans la fonction appellante.

    fn main() {
    println!("hello");
    ma_fonction();
    println!("world");
    }

    Ici hello et world seront bien afficher dans la console.

    Désolé pour le formatage de mon messgae. Je n'ai pas trouvé comment faire sur téléphone.
    Merci de la réponse, mais je trouve (ce n'est que mon avis), qu'on utilise un canon pour tuer une mouche...

    Ou alors il y a là quelque chose de plus profond dont je ne capte pas l'usage ou l'utilité.

  6. #6
    Membre Expert
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    887
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 887
    Par défaut
    Le ! est un type qui indique que le programme s'arrêtera dans cette fonction. Ça permet de le savoir dès la lecture du code ou de la doc sans avoir besoin de lire le code de la fonction.

    Donc non, pas comme en C/C++ et consorts. C'est un confort en somme.

  7. #7
    Membre confirmé
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Mai 2021
    Messages
    139
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2021
    Messages : 139
    Par défaut
    Citation Envoyé par OuftiBoy Voir le message
    Merci de la réponse, mais je trouve (ce n'est que mon avis), qu'on utilise un canon pour tuer une mouche...

    Ou alors il y a là quelque chose de plus profond dont je ne capte pas l'usage ou l'utilité.
    D'autres l'ont évoqué, mais les expressions Rust produisent une valeur avec un type. Notamment, l'usage de return n'est pas nécessaire à la fin d'une fonction Rust, puisque la valeur de la dernière expression est retournée.
    Le typage est un mécanisme profond en Rust, et intervient également dans la sémantique de prêt. Le type ! existe depuis longtemps (en nightly) et contribue à la pleine cohérence du système de typage: il permet de typer un horizon indépassable: arrêt, panique, boucle infinie, ...
    C'est aussi le type minimal en Rust au sens où il peut être converti en n'importe quel type.

    À quoi cela peut servir concrètement? Je n'utilise pas le type ! personnellement, et ma réponse est forcément limitée. À certaines simplifications dans le langage, comme indiqué par Uther. Par ailleurs, il permet éventuellement plus de flexibilité dans la mise en œuvre des panic! / exit / todo! / ..., par exemple, y compris dans un contexte multithread [playground]:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #![feature(never_type)]
    use std::{ process::exit, thread::spawn };
     
    fn div<F: Fn() -> ! + Send + Sync>(left: f64, right: f64, failure: F) -> f64 {
        if right == 0.0 { failure(); } else { left / right }
    }
     
    fn panique1() -> ! { panic!("panique 1!"); }
    fn panique2() -> ! { panic!("panique 2!"); }
     
    fn main() {
        for h in [ 
            spawn(|| println!("f64 -> {}", div(32.0, 5.0, panique1))),
            spawn(|| println!("f64 -> {}", div(32.0, 0.0, panique2))),
            spawn(|| println!("f64 -> {}", div(128.0, 16.0, || todo!()))),
            spawn(|| println!("f64 -> {}", div(8.0, 0.0, || unreachable!())))
        ] { let _ = h.join(); }
        println!("f64 -> {}", div(12.0, 5.0, ||exit(0)));
    }

  8. #8
    Membre confirmé
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Mai 2015
    Messages
    670
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Mai 2015
    Messages : 670
    Par défaut Merci à vous
    ,

    Merci pour vos réponses, il va me falloir un peu de temps pour les assimiler. Il me semble que ! a plusieurs "fonctionnaltés" qui n'ont pas forcément de relation entres-elles. J'ai repris les extraits qui m'ont "marqués" de vos réponses:

    imperio: Le ! est un type qui indique que le programme s'arrêtera dans cette fonction. Donc non, pas comme en C/C++ et consorts. C'est un confort en somme.
    Uther:Le point d’exclamation n'est pas pour le moment un type a part entière (il n'est utilisable qu'en retour de fonction).
    fdecode;il permet de typer un horizon indépassable: arrêt, panique, boucle infinie, ...
    fdecode:C'est aussi le type minimal en Rust au sens où il peut être converti en n'importe quel type.
    Pour imperio ! est un type "de confort" pour dire que le programme s'arrêtera dans la fonction. Uther ajoute que ce n'est pas pour le moment un type "a part entière" car il n'est utilisable qu'en retour de fonction. fdecode ajoute qu'il permet de typer un "horizon indépassable" (là j'ai du mal a saisir, que veut dire "typer un horizon (indépassable)", et que c'est le "type minimal" (donc, c'est un type ou pas ?), et qu'il peut être "converti en n'importe quel type.

    C'est pas mal d'usages pour un simple petit opérateur ! Je vous avoue que ce n'est pas facile a décrypter. C'est pas vraiment un type, mais c'est le type de base (un peu comme un "généric" ?) Utiliser un "type" pour indiquer qu'un programme s'arrêtera dans la fonction qui l'utilise, j'ai du mal a comprendre le "concept" caché derrière.

    Je vais potasser tout cela

    Encore merci à vous.
    BàV et Peace & Love.

    (PS: la définition de mon language Home se précise de plus en plus et j'avance bien, je n'ai pas abandonné, mais j'ai un peu "refactorisé" le code, et tant le langage que son compilateur se peaufine tout doucement. J'ai aussi commencer à attaquer la VM et le jeu d'instruction du CPU virtuel. Y'a encore du boulot, mais il me semble que j'avance sans trop de soucis, c'est juste beaucoup a faire...)

  9. #9
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 765
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 765
    Par défaut
    En effet c'est un peu compliqué car la situation est en train de changer.
    Actuellement si on utilise le compilateur stable, ! n'est utilisable qu'en type de retour d'une fonction qui ne peut pas se terminer. On ne peut pas encore l'utiliser directement comme type(ou composant d'un type) d'une variable. Mais dans un avenir proche (ou actuellement si on active la fonctionnalité expérimentale sur la version nightly du compilateur), le type ! sera utilisable partout en tant que type.

    Comme dit imperio, ça sert en partie d'indication : on a l'assurance qu'une fonction qui retourne ! ne se terminera pas. Mais ça aussi de vraies incidences techniques comme j'ai essayé de le montrer dans mes exemples.
    Il faut se représenter le type ! comme un type non instanciable, qui sert a définir des cas impossibles. Dans mon second exemple, le type Result<u32,!> indique un type qui ne peux pas avoir de cas d'erreur. Si on essaie de lui affecter une erreur, il refusera de compiler et du coup on a plus a traiter ce cas.

Discussions similaires

  1. [Oracle 9i] Dé activer les contrainte d'une table
    Par shaun_the_sheep dans le forum Oracle
    Réponses: 2
    Dernier message: 30/11/2006, 08h59
  2. [Postgres 8] Activer les index
    Par julienOriano dans le forum PostgreSQL
    Réponses: 7
    Dernier message: 27/10/2005, 23h59
  3. [EasyPHP] Activer les fonctions LDAP sur EasyPHP 1.8
    Par gregfly26 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 5
    Dernier message: 24/10/2005, 16h13
  4. Activer les suppression en cascade pour toutes contraintes
    Par jdeboer dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 07/10/2005, 10h50
  5. [eclipse3.0.1] activer les assertions
    Par MicroPuce dans le forum Eclipse Java
    Réponses: 4
    Dernier message: 15/04/2005, 15h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo