Rust中的panic宏

栏目: 编程语言 · Rust · 发布时间: 5年前

内容简介:如果主线程panic,则整个程序都会终止,如果不是主线程panic则只会终止子线程,其他线程不会异常终止.panic宏源码如下:

panic! 会立即终止程序,同时rust中的 OptionResult 出现 NoneErr 时都会触发 panic

如果主线程panic,则整个程序都会终止,如果不是主线程panic则只会终止子线程,其他线程不会异常终止.

panic宏源码如下:

#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable]
macro_rules! panic {
    () => ({
        panic!("explicit panic")
    });
    ($msg:expr) => ({
        $crate::rt::begin_panic($msg, &(file!(), line!(), __rust_unstable_column!()))
    });
    ($fmt:expr, $($arg:tt)+) => ({
        $crate::rt::begin_panic_fmt(&format_args!($fmt, $($arg)+),
                                    &(file!(), line!(), __rust_unstable_column!()))
    });
}

复制代码

有时我们希望将panic信息输出到日志中,标准库中的std::panic可以满足需求。可以设置一个类似于windows中的钩子函数,在panic发出后,在panic运行时之前,触发钩子函数去处理这个panic信息。panic信息被保存在PanicInfo结构体中。

///Registers a custom panic hook, replacing any that was previously registered.
pub fn set_hook(hook: Box<Fn(&PanicInfo) + Sync + Send + 'static>)
复制代码
The panic hook is invoked when a thread panics, but before the panic runtime is invoked. As such, the hook will run with both the aborting and unwinding runtimes. The default hook prints a message to standard error and generates a backtrace if requested, but this behavior can be customized with the set_hook and take_hook functions.
#[macro_use]
extern crate log;
extern crate simple_logger;
use std::thread;
use std::boxed::Box;
use std::panic;

fn main() {
    simple_logger::init().unwrap();
    panic::set_hook(Box::new(|panic_info|{
        error!("panic info: {:?},panic occurred in {:?}",panic_info.payload().downcast_ref::<&str>(),panic_info.location());
    }));

    thread::spawn(||{
        panic!("child thread panic test!");
    });

    loop{
    }
}
复制代码

downcast_ref的源码

#[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
        if self.is::<T>() {
            unsafe {
                Some(&*(self as *const Any as *const T))
            }
        } else {
            None
        }
    }
复制代码

但上面的代码如果是 Result 或者 Optionunwrap 触发的 panic ,则输出信息中 payload 项会是 None ,原因可以看上面 downcast_ref 的源码,进入 downcast_ref 后会有个判断条件如果不是类型 T 则就会返回 None 。如果我们想处理 unwrap 触发的 panic ,可以使用下面的示例代码,但是是有条件的,会用到 unsafe 代码段。

#[macro_use]
extern crate log;
extern crate simple_logger;
use std::thread;
use std::boxed::Box;
use std::panic;
use std::any::Any;

#[derive(Debug)]
struct PanicErr{
    info:String,
    value:i32,
}

fn main() {
    simple_logger::init().unwrap();
    panic::set_hook(Box::new(|panic_info|{
        unsafe {
            let s=&*(panic_info.payload() as *const Any as *const &str);
            error!("panic info: {},occurred in {:?}",s,panic_info.location());
        }
    }));

    thread::spawn(||{
        let e:Result<(),bool>=Err(false);
        e.unwrap();
    });

    let a:Result<(),PanicErr>=Err(PanicErr{info:"error info".to_string(),value:10});
    a.unwrap();

    loop{
    }
}

复制代码

参考文档:std::panic


以上所述就是小编给大家介绍的《Rust中的panic宏》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

网络、群体与市场

网络、群体与市场

大卫·伊斯利(David Esley)、乔恩·克莱因伯格(Jon Kleinberg) / 李晓明、王卫红、杨韫利 / 清华大学出版社 / 2011-10-1 / CNY 69.00

过去十年来,现代社会中复杂的连通性向公众展现出与日俱增的魅力。这种连通性在许多方面都有体现并发挥着强大的作用,包括互联网的快速成长、全球通信的便捷,以及新闻与信息(及传染病与金融危机)以惊人的速度与强度传播的能力。这种现象涉及网络、动机和人们的聚合行为。网络将人们的行为联系起来,使得每个人的决定可能对他人产生微妙的后果。 本书是本科生的入门教材,同时也适合希望进入相关领域的高层次读者。它从交......一起来看看 《网络、群体与市场》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

MD5 加密
MD5 加密

MD5 加密工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具