2015-07-03 89 views
3

下面的代碼編譯(特別是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)); 
} 

但是,如果我有

where F: str::FromStr 

然後更換where語句爲my_force_parse它不。不應該程序收集MyError從#[派生(調試)]屬性實現調試嗎?

回答

2

MyError實現Debug ... 無條件。相反,只要所有必需的通用參數實施它,它就實現它。從本質上講,#[derive(Debug)]屬性擴展到東西大致是:

impl<F> MyError<F> where F: Debug { 
    ... 
} 

畢竟,如果F沒有實現DebugMyError不能提供一個實現。

此外,看起來好像where F: str::FromStr + fmt::Debug也是不夠的。據推測,魯斯特要麼不夠聰明,不能認識到F: Debug = MyError<F>: Debug,或者假設有問題。

+2

對'impl'的約束實際上是'F :: Err:Debug',因爲枚舉變量'Parse'包含'F :: Err',而不是'F'。 (儘管'rustc --pretty = expanded' *也會在'impl'上放一個'F:Debug'約束,但我看不出原因。) –