Gestion d’erreurs
Orestis Malaspinas
panic!()
panic!("texte")
."texte"
.
fn elem(v: &[i32], i: usize) -> i32 {
if i >= v.len() {
panic!("Erreur fatale!");
}
// assert!(i < v.len(), "Erreur fatale!"); // ceci est équivalent
v[i]
}
fn main() {
let v = [1, 2, 3, 4];
elem(&v, 100);
}
Avec l’appel RUST_BACKTRACE=1
on peut remonter la pile d’appels (debugging).
$ RUST_BACKTRACE=1 cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/ma_librairie`
thread 'main' panicked at 'Erreur fatale!', src/main.rs:5:3
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::print
at libstd/sys_common/backtrace.rs:71
at libstd/sys_common/backtrace.rs:59
2: std::panicking::default_hook::{{closure}}
at libstd/panicking.rs:211
3: std::panicking::default_hook
at libstd/panicking.rs:227
4: std::panicking::rust_panic_with_hook
at libstd/panicking.rs:477
5: std::panicking::begin_panic
at /checkout/src/libstd/panicking.rs:411
6: ma_librairie::elem
at src/main.rs:5
7: ma_librairie::main
at src/main.rs:12
8: std::rt::lang_start::{{closure}}
at /checkout/src/libstd/rt.rs:74
9: std::panicking::try::do_call
at libstd/rt.rs:59
at libstd/panicking.rs:310
10: __rust_maybe_catch_panic
at libpanic_unwind/lib.rs:102
11: std::rt::lang_start_internal
at libstd/panicking.rs:289
at libstd/panic.rs:392
at libstd/rt.rs:58
12: std::rt::lang_start
at /checkout/src/libstd/rt.rs:74
13: main
14: __libc_start_main
15: _start
assert!(cond, "Texte");
fn main() {
let num = 1;
let denum = 0;
assert!(denum != 0, "Le dénominateur doit être non nul.");
let _total = num / denum;
}
assert_eq!(lhs, rhs, "Texte");
fn main() {
let a = 1;
let b = 0;
assert_eq!(a, b, "A et b devraient être égales.");
}
assert_ne!(lhs, rhs, "Texte");
fn main() {
let a = 1;
let b = 0;
assert_ne!(a, b, "A et b devraient être différentes.");
}
Un type énuméré particulièrement utile est le type Option
enum Option<T> { // <T> est une notation pour un type générique
Some(T),
None,
}
Exmple: la division
fn main() {
let num = 1;
let denum = 4;
let div =
if denum == 0 {
None
} else {
Some(num / denum)
};
match div {
Some(d) => println!("{} divisé par {} donne {}", num, denum, d),
None => println!("Cette division n'existe pas."),
}
}
Il est commun que des fonction retournent des Option
.
Pour un traitement plus fin des erreurs l’enum
enum Result<T, E> {
Ok(T),
Err(E),
}
Contient le un élément de type T
quand tout se passe bien et E
pour l’erreur.
fn elem(v: &[i32], i: usize) -> Result<i32, &str> {
if i >= v.len() {
return Err("L'index est trop grand!")
} else {
Ok(v[i])
}
}
fn main() {
let v = [1, 2, 3, 4];
match elem(&v, 100) {
Ok(i) => println!("L'élément est {}", i),
// Err(error) => panic!("The problem is {:?}", error),
Err(_) => println!("Mince ça a raté."),
}
}