对于致命的错误处理,我正在使用panic!
宏,但我更喜欢有一个没有打印文件/行信息的宏,只有错误信息。
我看了the macro documentation,但我的理解有点不稳定。
我查看了panic!
宏的来源,但它正在调用函数来完成它的工作,其中文件和行信息是操作的一个组成部分,所以我不能只调整它。
我查看了println!
宏,看起来更有前景,但我有两个问题,我不知道如何解决。
macro_rules! die {
() => (print!("\n"));
($fmt:expr) => (print!(concat!($fmt, "\n")));
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*); exit(-1));
}
如果我将exit()
调用放在最后一行,就像我在调用它时遇到语法错误一样。
如果删除exit()
,我不会抱怨宏,但是这段代码无法编译:
let file = match File::open(&path) {
Err(why) => die!("Couldn't open {}: {}", display, why.description()),
Ok(file) => file,
};
当die!
替换为panic!
时,它会编译。我假设有一些关于panic!
的魔法告诉编译器它永远不会返回?
答案 0 :(得分:3)
首先,如果我将
exit()
调用放在最后一行,就像我在调用它时遇到语法错误一样。
这是因为宏应该扩展为单个项目,并在此处扩展为两个。您可以简单地将调用包装在一个{}
块中,只要您将调用限定为exit
,它就会正常工作。
({ print!(concat!($fmt, "\n"), $($arg)*); std::process::exit(-1) });
如果我删除
exit()
,我就不会抱怨宏,但此代码无法编译。而die
替换为panic
时会编译。我假设有一些关于panic
的魔法告诉编译器它永远不会返回?
它不像!
类型那么神奇。 panic
和exit
函数都返回!
这是一个没有值的类型:它无法构造。
这足以让编译器知道那些函数永远不会返回(它们发散),因此从类型检查的角度来看,!
被认为是所有类型的子类型,并且不会导致问题