以下代码可以编译(特别是 MyError 被识别为具有调试特性):
use std::str;
use std::fmt;
#[derive(Debug)]
enum MyError<F> where F: str::FromStr {
Parse(F::Err),
Space,
}
fn my_parse<F>(s: String) -> Result<F,MyError<F>>
where F: str::FromStr {
match s.len() {
0 => Err(MyError::Space),
_ => s.parse::<F>().map_err(|err| MyError::Parse(err)),
}
}
fn my_force_parse<F>(s: String) -> F
where F: str::FromStr, MyError<F>: fmt::Debug {
my_parse::<F>(s).unwrap()
}
fn main() {
println!("hi");
let s = "nope".to_string();
println!("{}", my_force_parse::<i64>(s));
}
但是如果我将 my_force_parse
的 where 语句替换为
where F: str::FromStr
然后就没有了。程序不应该从 #[derive(Debug)] 属性中收集到 MyError 实现 Debug 吗?
最佳答案
MyError
没有实现Debug
... 无条件地。相反,只要所有必需的通用参数也实现它,它就会实现它。本质上,#[derive(Debug)]
属性扩展为大致如下:
impl<F> MyError<F> where F: Debug {
...
}
毕竟,如果F
没有实现 Debug
, MyError
无法提供实现。
此外,它看起来好像 where F: str::FromStr + fmt::Debug
也是不够的。据推测,Rust 要么不够聪明,无法意识到 F: Debug
⇒ MyError<F>: Debug
,或者这样假设有问题。
关于rust - 派生 Debug 的枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31202590/