2015-11-28 84 views
3

我想添加类型参数给我已经有的代码。但我有原来的代码看起来像这样的麻烦如何表达绑定在另一个泛型类型的特征绑定的类型参数上的特征?

fn parse_row(text: String) -> Result<Vec<u32>> { 
    text.split(" ") 
     .map(|s| s.to_owned() 
      .parse::<u32>() 
      .map_err(|e| err(&e.to_string()[..])) 
     ) 
     .collect::<Result<Vec<u32>>>() 
} 

这里是通用版本:

fn parse_row<Item>(text: String) -> Result<Vec<Item>> 
    where Item: Copy + Debug + FromStr + Display 
{ 
    text.split(" ") 
     .map(|s| s.to_owned() 
      .parse::<Item>() 
      .map_err(|e| err(&e.to_string()[..])) 
     ) 
     .collect::<Result<Vec<Item>>>() 
} 

我得到的错误是:

src/grid.rs:108:35: 108:46 error: no method named `to_string` found for type `<Item as core::str::FromStr>::Err` in the current scope 
src/grid.rs:108    .map_err(|e| err(&e.to_string()[..])) 
               ^~~~~~~~~~~ 
note: in expansion of closure expansion 
src/grid.rs:108:23: 108:52 note: expansion site 
note: in expansion of closure expansion 
src/grid.rs:106:14: 108:53 note: expansion site 
src/grid.rs:108:35: 108:46 note: the method `to_string` exists but the following trait bounds were not satisfied: `<Item as core::str::FromStr>::Err : core::fmt::Display` 

<Item as core::str::FromStr>::Err指的是与Item的相关的类型参数执行(我花了一段时间才弄清楚!)。但我怎么能表达这种我实际上不知道的类型具有Display特质?

回答

3

这最初是因为我不明白它指的是哪个Err - 并且认为它是Result的错误类型参数。一旦我发现FromStr有自己的Err类型参数,我只需要弄清楚如何表达这个约束。这里,它是:

fn parse_row<Item, E>(text: String) -> Result<Vec<Item>> 
    where Item: Copy + Debug + FromStr<Err = E>, 
      E: Display 
{ 
    text.split(" ") 
     .map(|s| s.to_owned() 
      .parse::<Item>() 
      .map_err(|e| err(&e.to_string()[..])) 
     ) 
     .collect::<Result<Vec<Item>>>() 
} 
+3

它没有做太大的区别,但你并不需要'E'类型参数,你可以要求直接对相关类型这样的约束:'其中项目: Copy + Debug + FromStr,Item :: Err:Display' – bluss

+0

@bluss谢谢!这好多了。 –

+0

它也可能是你不需要':: '和':: <结果>'那些应被推断。 – Shepmaster