Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Rust 1.47.0 est disponible et s'accompagne de la prise en charge par défaut de LLVM 11
Ainsi que de neuf API qui passent en version stable dans la bibliothèque

Le , par Stéphane le calme

23PARTAGES

16  0 
L'équipe responsable du développement de Rust a annoncé la disponibilité de Rust 1.47.0. Cette version ne contient aucune nouvelle fonctionnalité de langage, bien qu'elle ajoute une fonctionnalité de bibliothèque standard longtemps attendue.

Les traits sur des tableaux plus grands

Un trait est un agrégat de méthodes définies pour un type inconnu : Self. Elles peuvent accéder aux autres méthodes déclarées dans le même trait. Les traits peuvent être implémentés pour n'importe quel type de donnée. Dans l'exemple ci-dessous, nous définissons Animal, un groupe de méthodes. Le trait Animal est alors implémenté pour le type Sheep, permettant l'utilisation des méthodes de Animal avec une instance du type Sheep.

Code Rust : Sélectionner tout
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
struct Sheep { naked: bool, name: &'static str }
 
trait Animal {
    // Méthode statique; `Self` fait référence au type ayant implémenté 
    // le trait.
    fn new(name: &'static str) -> Self;
 
    // Méthode d'instance; Elles renverront une chaîne de caractères.
    fn name(&self) -> &'static str;
    fn noise(&self) -> &'static str;
 
    // Les traits peuvent fournir une implémentation par défaut.
    fn talk(&self) {
        println!("{} says {}", self.name(), self.noise());
    }
}
 
impl Sheep {
    fn is_naked(&self) -> bool {
        self.naked
    }
 
    fn shear(&mut self) {
        if self.is_naked() {
            // Les méthodes de `Self` peuvent utiliser les méthodes déclarées 
            // par le trait.
            println!("{} is already naked...", self.name());
        } else {
            println!("{} gets a haircut!", self.name);
 
            self.naked = true;
        }
    }
}
 
// Implémentation des services du trait `Animal` 
// pour le type `Sheep`.
impl Animal for Sheep {
    // En l'occurrence, `Self` fait référence à `Sheep`.
    fn new(name: &'static str) -> Sheep {
        Sheep { name: name, naked: false }
    }
 
    fn name(&self) -> &'static str {
        self.name
    }
 
    fn noise(&self) -> &'static str {
        if self.is_naked() {
            "baaaaah?"
        } else {
            "baaaaah!"
        }
    }
 
    // L'implémentation par défaut fournie par le trait 
    // peut être réécrite.
    fn talk(&self) {
        // Par exemple, nous pourrions fournir une description plus précise.
        println!("{} pauses briefly... {}", self.name, self.noise());
    }
}
 
fn main() {
    // Typer l'identificateur est nécessaire dans ce cas de figure.
    let mut dolly: Sheep = Animal::new("Dolly");
    // TODO ^ Essayez de supprimer le type annoté.
 
    dolly.talk();
    dolly.shear();
    dolly.talk();
}

Rust n'a actuellement pas de moyen d'être générique sur des valeurs entières. Cela a longtemps posé des problèmes avec les tableaux, car les tableaux ont un entier dans leur type; [T; N] est le type d'un tableau de type T de longueur N. Comme il n'y a aucun moyen d'être générique sur N, vous devez implémenter manuellement des traits pour les tableaux pour chaque N que vous souhaitez prendre en charge. Pour la bibliothèque standard, il a été décidé de prendre en charge une longueur pouvant aller jusqu'à N=32.

L'équipe a travaillé sur une fonctionnalité appelée const generics qui vous permettrait d'être générique sur N. Le cœur de cette fonctionnalité a été implémenté dans le compilateur, et il a été décidé que la fonctionnalité est suffisamment avancée pour que la bibliothèque standard l'utilise pour implémenter des traits sur des tableaux de toute longueur. En pratique, cela signifie que si vous essayez de faire quelque chose comme ça sur Rust 1.46:

Code Rust : Sélectionner tout
1
2
3
4
5
fn main() {
    let xs = [0; 34];
 
    println!("{:?}", xs);
}

Vous obtiendrez cette erreur :

error[E0277]: arrays only have std trait implementations for lengths 0..=32
 --> src/main.rs:4:22
  |
4 |     println!("{:?}", xs);
  |                      ^^ the trait `std::array::LengthAtMost32` is not implemented for `[{integer}; 34]`
  |
  = note: required because of the requirements on the impl of `std::fmt::Debug` for `[{integer}; 34]`
  = note: required by `std::fmt::Debug::fmt`
  = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
Mais avec Rust 1.47, le tableau s'affichera correctement.

Cela devrait rendre les tableaux beaucoup plus utiles pour les développeurs, bien qu'il faudra attendre que la fonctionnalité const generics soit stabilisée pour que les bibliothèques puissent faire ce type d'implémentation pour leurs propres caractéristiques. L'équipe n'a pas encore arrêté de date à ce sujet.


Des traces plus courtes

Avec Rust 1.18, l'équipe a apporté quelques modifications aux traces que rustc imprimerait en cas de panique (situation obtenue lorsque les programmes Rust atteignent un état où une erreur critique est survenue). Il y a un certain nombre de choses dans une trace qui ne sont pas utiles la plupart du temps. Cependant, à un moment donné, ils ont régressé. Dans Rust 1.47.0, le coupable a été trouvé, et cela a maintenant été corrigé. Depuis la régression, ce programme:

Code Rust : Sélectionner tout
1
2
3
fn main() {
    panic!();
}

Produit une trace comme celle-ci :

thread 'main' panicked at 'explicit panic', src/main.rs:2:5
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:78
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:59
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1076
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1537
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:62
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:49
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:198
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:217
  10: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:526
  11: std::panicking::begin_panic
             at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/panicking.rs:456
  12: playground::main
             at src/main.rs:2
  13: std::rt::lang_start::{{closure}}
             at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/rt.rs:67
  14: std::rt::lang_start_internal::{{closure}}
             at src/libstd/rt.rs:52
  15: std::panicking::try::do_call
             at src/libstd/panicking.rs:348
  16: std::panicking::try
             at src/libstd/panicking.rs:325
  17: std::panic::catch_unwind
             at src/libstd/panic.rs:394
  18: std::rt::lang_start_internal
             at src/libstd/rt.rs:51
  19: std::rt::lang_start
             at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/rt.rs:67
  20: main
  21: __libc_start_main
  22: _start
Désormais, dans Rust 1.47.0, vous verrez plutôt ceci :

thread 'main' panicked at 'explicit panic', src/main.rs:2:5
stack backtrace:
   0: std::panicking::begin_panic
             at /rustc/d6646f64790018719caebeafd352a92adfa1d75a/library/std/src/panicking.rs:497
   1: playground::main
             at ./src/main.rs:2
   2: core::ops::function::FnOnce::call_once
             at /rustc/d6646f64790018719caebeafd352a92adfa1d75a/library/core/src/ops/function.rs:227
Cela permet de voir beaucoup plus facilement d'où vient la panique et vous pouvez toujours définir RUST_BACKTRACE=full si vous souhaitez tout voir.

LLVM 11

Rust 1.47.0 s'accompagne d'une mise à niveau vers LLVM 11. Le compilateur prend toujours en charge la compilation avec des versions de LLVM jusqu'à la version 8. Cependant, par défaut, c'est sur LLVM 11 que vous serez.

Changements dans la bibliothèque

Neuf API sont désormais disponibles en version stable :
  • Ident::new_raw
  • Range::is_empty
  • RangeInclusive::is_empty
  • Result::as_deref
  • Result::as_deref_mut
  • Vec::leak
  • pointer::offset_from
  • f32::TAU
  • f64::TAU

Source : note de version

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de Pyramidev
Expert confirmé https://www.developpez.com
Le 08/10/2020 à 22:20
Tiens, Rust ajoute la constante TAU. Ce n'est pas la fonctionnalité du siècle, mais c'est amusant.

Cela me rappelle Python 3.6 dans lequel Guido van Rossum avait validé l'ajout de math.tau (PEP 628) malgré la protestation de Raymond Hettinger.
Citation Envoyé par Raymond Hettinger
* The push to use of "tau" has the flavor a political fad or wishful thinking that may or may not succeed. The math module should only implement established practice.

* Since not everyone knows or uses tau, its use would tend to make code less clear. As a reviewer, I would ask that code like "from math import tau" to be changed to "from math import tau as twopi". The latter is more clear to most users (how many people would recognize "tau * r" when it occurs in the middle of a larger expression?).

* I've surveyed engineers in my recent Python courses (often with Physics, EE, MaterialScience, DSP, or CompSci backgrounds and not a single one of them had heard of this constant).

* If people really wanted this, we would be seeing more cases of "tau = 2.0 * math.pi" in code. Google searches and Github code search shows that this is very rare.

* It is already trivial to write "tau=2.0*pi" so why bother?

* Adding mysteriously named constants degrades the usability of the math module where many of the tools are currently self-evident but not all (
tau is a number, gamma is a function, and what the heck is a frexp?).

* Also, the name "tau" is already used for other purposes in various contexts (shear stress, proper time in relativity, torque, tau lepton, optical depth in astronomy, time contacts in RC circuits, etc).
Citation Envoyé par Guido van Rossum
It's okay if Python occasionally shows its lighter side in unexpected places. Think of the delight of future (junior) high schoolers who discover that Python participates in the tau debate. :-)
Source : https://bugs.python.org/issue12345
0  0