如何在Rust中从函数返回一个泛型类型的向量,编译器错误E0277说我需要实现调试,为什么?

w3nuxt5m  于 2022-12-04  发布在  其他
关注(0)|答案(2)|浏览(376)

很难理解泛型的概念。我如何从一个函数返回一个泛型值的向量?我想输入文本,输出是字符串或整数的向量。但是,编译器给了我error[E0277]: <T as FromStr>::Err doesn't implement Debug。它告诉我需要实现'Debug'特征?但是我不明白为什么。我如何简单地返回一个任意类型的向量?

use std::str::FromStr;

    fn main() {
    let a: Vec<u32> = text_to_vec("1 2 3 4");
    }

fn text_to_vec<T: FromStr>(text: &str) -> Vec<T> {
    let mut list = Vec::new();

    for word in text.split(" "){
        if let w = word {
            let w = w.parse().unwrap();
            list.push(w);
        }
    }
    return list;
}

在这个例子中我期望得到一个u32整数的向量。

jgwigjjp

jgwigjjp1#

错误如下:

error[E0277]: `<T as FromStr>::Err` doesn't implement `Debug`
  --> src/main.rs:12:21
   |
12 |             let w = w.parse().unwrap();
   |                     ^^^^^^^^^ ------ required by a bound introduced by this call
   |                     |
   |                     `<T as FromStr>::Err` cannot be formatted using `{:?}` because it doesn't implement `Debug`
   |
   = help: the trait `Debug` is not implemented for `<T as FromStr>::Err`
note: required by a bound in `Result::<T, E>::unwrap`
help: consider further restricting the associated type
   |
7  | fn text_to_vec<T: FromStr>(text: &str) -> Vec<T> where <T as FromStr>::Err: Debug {
   |                                                  ++++++++++++++++++++++++++++++++

您应该阅读完整的错误消息,因为它解决了Debug需求的来源,甚至提供了解决方案。
调用.unwrap()需要错误类型实现Debug,因为如果发生错误,它将显示一条包含错误的消息。
错误的最后一部分建议加入where子句,以限制从.parse()传回的错误类型实作Debug
如果你不想添加约束,另一个解决方案是忽略或自己记录错误。使用match的方法会很好地工作:

match w.parse() {
    Ok(w) => list.push(w),
    Err(_) => println!("failed to parse {w}"),
}
4uqofj5v

4uqofj5v2#

这里的编译器错误是由unwrap引起的。unwrap创建了一个panic,默认情况下,它试图打印出错误。这就是为什么它要求<T as FromStr>::Err实现Debug。然而,您的函数并不要求这样做。
我建议你用迭代器实现你的函数,并返回一个Result,然后你可以在其他地方展开。

use std::str::FromStr;

fn main() {
    let a: Vec<u32> = text_to_vec("1 2 3 4").unwrap();
}

fn text_to_vec<T: FromStr>(text: &str) -> Result<Vec<T>, <T as FromStr>::Err> {
    text.split(" ").map(|word| word.parse()).collect()
}

否则,您必须将该绑定添加到函数中:

use std::fmt::Debug;

fn text_to_vec_unwrap<T>(text: &str) -> Vec<T>
where
    T: FromStr,
    <T as FromStr>::Err: Debug,
{
    text.split(" ").map(|word| word.parse().unwrap()).collect()
}

相关问题