fnmain(){panic!("crash and burn");}Compiling playground v0.0.1(/playground)Finished dev [unoptimized + debuginfo]target(s)in0.57s
Running `target/debug/playground`
thread 'main' panicked at 'crash and burn', src/main.rs:2:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
下面是一段官方文档
下面是一段示例代码:
fnmain(){let v =vec![1,2,3];
v[99];}Compiling playground v0.0.1(/playground)Finished dev [unoptimized + debuginfo]target(s)in0.85s
Running `target/debug/playground`
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 99', src/main.rs:4:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Finished dev [unoptimized + debuginfo]target(s)in0.00s
Running `target/debug/panic`
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 99', libcore/slice/mod.rs:2448:10
stack backtrace:0:std::sys::unix::backtrace::tracing::imp::unwind_backtrace
at libstd/sys/unix/backtrace/tracing/gcc_s.rs:491:std::sys_common::backtrace::print
at libstd/sys_common/backtrace.rs:71
at libstd/sys_common/backtrace.rs:592:std::panicking::default_hook::{{closure}}
at libstd/panicking.rs:2113:std::panicking::default_hook
at libstd/panicking.rs:2274:<std::panicking::begin_panic::PanicPayload<A>ascore::panic::BoxMeUp>::get
at libstd/panicking.rs:4765:std::panicking::continue_panic_fmt
at libstd/panicking.rs:3906:std::panicking::try::do_call
at libstd/panicking.rs:3257:core::ptr::drop_in_place
at libcore/panicking.rs:778:core::ptr::drop_in_place
at libcore/panicking.rs:599:<usizeascore::slice::SliceIndex<[T]>>::index
at libcore/slice/mod.rs:244810:core::slice::<implcore::ops::index::Index<I>for[T]>::index
at libcore/slice/mod.rs:231611:<alloc::vec::Vec<T>ascore::ops::index::Index<I>>::index
at liballoc/vec.rs:165312:panic::main
at src/main.rs:413:std::rt::lang_start::{{closure}}
at libstd/rt.rs:7414:std::panicking::try::do_call
at libstd/rt.rs:59
at libstd/panicking.rs:31015: macho_symbol_search
at libpanic_unwind/lib.rs:10216:std::alloc::default_alloc_error_hook
at libstd/panicking.rs:289
at libstd/panic.rs:392
at libstd/rt.rs:5817:std::rt::lang_start
at libstd/rt.rs:7418:panic::main
let f:u32=File::open("hello.txt");
error[E0308]: mismatched types
--> src/main.rs:4:18|4|let f:u32=File::open("hello.txt");|^^^^^^^^^^^^^^^^^^^^^^^ expected u32, found enum
`std::result::Result`
|= note: expected type `u32`
found type `std::result::Result<std::fs::File,std::io::Error>`
usestd::fs::File;fnmain(){let f =File::open("hello.txt");let f =match f{Ok(file)=> file,Err(error)=>{panic!("Problem opening the file {:?}",error)},};}
thread 'main' panicked at 'Problem opening the file:Error{ repr:Os{ code:2, message:"No such file or directory"}}', src/main.rs:9:12
匹配不同的错误
此时有Errkind方法可以调用。
目标是实现不同错误下的不同panic!。
usestd::fs::File;usestd::io::ErrorKind;fnmain(){let f =File::open("hello.txt");let f =match f
{Ok(file)=> file,Err(error)=>match error.kind(){ErrorKind::NotFound=>matchFile::creat("hello.txt"){Ok(fc)=> fc,Err(e)=>panic!("Problem creating the file {:?}",e),},
other_error =>panic!("Problem opening the file: {:?}",other_error),},};}
usestd::fs::File;fnmain(){let f =File::open("hello.txt").unwrap();}
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value:Error{
repr:Os{ code:2, message:"No such file or directory"}}',
src/libcore/result.rs:906:4
usestd::io;usestd::io::Read;usestd::fs::File;fnread_username_from_file()->Result<String,io::Error>{let f =File::open("hello.txt");letmut f =match f
{Ok(file)=> file,Err(e)=>returnErr(e),};letmut s =String::new();match f.read_to_string(&mut s){Ok(_)=>Ok(s),Err(e)=>Err(e),}}
下面是官方文档的描述
传播错误的简写:?运算符
使用?运算符来实现Result中match表达式
usestd::io;usestd::io::Read;usestd::fs::File;fnread_username_from_file()->Result<String,io::Error>{letmut f =File::open("hello.txt")?;letmut s =String::new();
f.read_to_string(&mut s)?;Ok(s)}
Form trait是定义在标准库之下的函数,用来将错误从一种类型转换为另一种类型,此处的?就使用的这种方法,这种方法在函数返回单个错误类型来代表所有可能失败的方式时很有用,即便它可能由多种原因导致错误。只要每一个错误类型都实现了 from 函数来定义如何将自身转换为返回的错误类型,? 运算符会自动处理这些转换。
上述代码还可以更加简化:
fnmain(){usestd::io;usestd::io::Read;usestd::fs::File;fnread_username_from_file()->Result<String,io::Error>{letmut s =String::new();File::open("hello.txt")?.read_to_string(&mut s)?;Ok(s)}}
usestd::fs::File;fnmain(){let f =File::open("hello.txt")?;}
error[E0277]: the `?` operator can only be used in a function that returns
`Result` or `Option` (or another typethat implements `std::ops::Try`)--> src/main.rs:4:13|4|let f =File::open("hello.txt")?;|^^^^^^^^^^^^^^^^^^^^^^^^ cannot use the `?` operator in a
function that returns `()`
|= help: the trait `std::ops::Try` is not implemented for `()`
= note: required by `std::ops::Try::from_error`
main函数的返回值是有限制的,它的返回值有一个是(),出于方便,另一个为Result<T,E>.
usestd::error::Error;usestd::fs::File;fnmain()->Result<(),Box<dynError>>{let f =File::open("hello.txt")?;Ok(())}
loop{// --snip--let guess:i32=match guess.trim().parse(){Ok(num)=> num,Err(_)=>continue,};if guess <1|| guess >100{println!("The secret number will be between 1 and 100.");continue;}match guess.cmp(&secret_number){// --snip--}}
使用这种方法进行函数检查比较冗余,可以采用新的方法,构建一个impl程序块。
fnmain(){pubstructGuess{
value:i32,}implGuess{pubfnnew(value:i32)->Guess{if value <1|| value >100{panic!("Guess value must be between 1 and 100, got {}.", value);}Guess{
value
}}pubfnvalue(&self)->i32{self.value
}}}