当我的 T 与 Into<String> 绑定时,特征绑定 `String: From<&T>` 不满足

The trait bound `String: From<&T>` is not satisfied when my T is bound with Into<String>

我有以下代码,

impl<T: Debug + Into<String> + Clone> TryFrom<Vec<T>> for Positionals {
  type Error = &'static str;
  fn try_from(mut vec: Vec<T>) -> Result<Self, Self::Error> {
    let mystr: String = vec.get(0).unwrap().into();

那个代码产生了这个错误,

error[E0277]: the trait bound `String: From<&T>` is not satisfied
  --> bin/seq.rs:21:43
   |
21 |         let mystr: String = vec.get(0).unwrap().into();
   |                                                 ^^^^ the trait `From<&T>` is not implemented for `String`
   |
   = note: required because of the requirements on the impl of `Into<String>` for `&T`
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement

我很困惑为什么这会产生错误,因为我在 Vec<T> 上绑定了一个特性,这样 T 必须实现 Into<String>,还需要什么?我不明白这是为什么,我删除了 into(),我得到

let mystr: String = vec.get(0).unwrap();
           ------   ^^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&T`

如何让 Vec<T> 中的 T 变为 String?我做Vec<T>而不做Vec<String>的原因是因为我也想支持Vec<&str>

您的代码的问题在于您的向量为您提供了 引用 ,即 &String。虽然 Into<String> 是为 String 简单实现的,但它没有为 &String 实现,这需要克隆。您可以实施编译器的建议并添加一个 where T: From<&String>,但它需要额外调整生命周期并且将再次不支持 &str.

要同时支持 &strString,您可以使用 AsRef<str>:

impl<T: Debug + Clone + AsRef<str>> TryFrom<Vec<T>> for Positionals {
    type Error = &'static str;
    fn try_from(mut vec: Vec<T>) -> Result<Self, Self::Error> {
        let mystr: String = vec[0].as_ref().into();
        todo!()
    }
}

通过以下两个编译:

Positionals::try_from(vec!["foo",]);
Positionals::try_from(vec!["foo".to_owned(),]);

Playground

旁注:您可以使用 vec[0] 而不是 vec.get(0).unwrap()。 (为了防止不希望的移动出向量,只需添加一个借位,即 &vec[0]。)