$ cargo run
Compiling panic v0.1.0 (file:///projects/panic)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.27s
Running `target/debug/panic`
thread 'main' panicked at src/main.rs:4:6:
index out of bounds: the len is 3 but the index is 99
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
$ RUST_BACKTRACE=1 cargo run
thread 'main' panicked at src/main.rs:4:6:
index out of bounds: the len is 3 but the index is 99
stack backtrace:
0: rust_begin_unwind
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/std/src/panicking.rs:692:5
1: core::panicking::panic_fmt
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/core/src/panicking.rs:75:14
2: core::panicking::panic_bounds_check
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/core/src/panicking.rs:273:5
3: <usize as core::slice::index::SliceIndex<[T]>>::index
at file:///home/.rustup/toolchains/1.85/lib/rustlib/src/rust/library/core/src/slice/index.rs:274:10
4: core::slice::index::<impl core::ops::index::Index<I> for [T]>::index
at file:///home/.rustup/toolchains/1.85/lib/rustlib/src/rust/library/core/src/slice/index.rs:16:9
5: <alloc::vec::Vec<T,A> as core::ops::index::Index<I>>::index
at file:///home/.rustup/toolchains/1.85/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:3361:9
6: panic::main
at ./src/main.rs:4:6
7: core::ops::function::FnOnce::call_once
at file:///home/.rustup/toolchains/1.85/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
usestd::fs::File;usestd::io::ErrorKind;fnmain(){letfile_result=File::open("hello.txt");letfile=matchfile_result{Ok(file)=>file,Err(e)=>matche.kind(){ErrorKind::NotFound=>matchFile::create("hello.txt"){Ok(fc)=>fc,Err(e)=>panic!("Problem creating the file: {:?}",e),},_=>panic!("Problem opening the file: {:?}",e),},};}
fnmain(){letfile_result=File::open("hello.txt");letfile_expect=file_result.expect("Failed to open hello.txt");letfile_unwrap=file_result.unwrap();letfile_unwrap_or_else=file_result.unwrap_or_else(|e|{ife.kind()==ErrorKind::NotFound{File::create("hello.txt").unwrap_or_else(|e|{panic!("Problem creating the file: {:?}",e);})}else{panic!("Problem opening the file: {:?}",e);}});}
上述的代码虽然完备,但是有些冗长,Rust 也经常使用这种错误处理方式,因此提供了 ? 运算符,可以简化错误处理。简单来讲,其定义就是上面代码第一个 match 的语法糖:如果 Result 的值是 Ok,则 Ok 中的值将从表达式之中返回,程序继续执行,如果 Result 的值是 Err,则 Err 中的值将作为整个函数的返回值被返回,就好像使用了 return 一样,从而将错误传播到调用代码(调用的上一层)。
但是对被使用 ? 运算符调用了的错误值会经过 from 函数,其定义在标准库中的 From 特征/Trait 之中,当 ? 运算符调用 from 函数时,接收到的错误类型会被转换为当前函数返回类型中定义的错误类型。
pubfnadd(left: u64,right: u64)-> u64{left+right}fnpanic_add(left: u64,right: u64)-> u64{panic!("This function will panic");}#[cfg(test)]modtests{usesuper::*;#[test]fnit_works(){letresult=add(2,2);assert_eq!(result,4);}#[test]#[should_panic(expected = "This function will panic")]fnit_works_with_panic(){panic_add(2,2);}}