1

我试图理解 Rust 中的泛型。我无法理解这里出了什么问题

fn say<T>(msg: &T)  {
    let slen = msg.chars().count();
    if slen > 0 {
        println!("Char Count {} " ,slen);
    } 
}


fn main() {
    let msg = String::from("Hello World from Rust!!!");
    say::<String>(&msg);
}

编译错误:

error[E0599]: no method named `chars` found for reference `&T` in the current scope
 --> hell.rs:4:20
  |
4 |     let slen = msg.chars().count();
  |                    ^^^^^ method not found in `&T`
4

2 回答 2

2

您的函数say假定输入具有chars创建迭代器的方法chars。这适用的类型并不多,因此使其通用化似乎不是很有用。

具有chars迭代器方法的主要两种类型是String&str。如果您将参数更改为,&str那么您可以接受其中任何一个:

fn say(msg: &str)  {
    let slen = msg.chars().count();
    if slen > 0 {
        println!("Char Count {} ", slen);
    } 
}


fn main() {
    let msg: String = String::from("Hello World from Rust!!!");
    say(&msg);
    let msg: &str = "Hello World from Rust!!!";
    say(msg);
}

也可以看看:

于 2021-03-25T14:30:38.473 回答
2

Rust 泛型背后的想法是泛型类型既受 trait bounds限制又被定义。由一组特征限制的泛型函数T可能会假设T具有来自这些特征的方法,仅此而已。由于T不受任何特征的约束,因此没有T::chars()方法可以调用。

要编写调用任何现有 trait 未提供的方法的通用代码,例如chars(),您可以编写自己的 trait 来提供所需的功能,并为您需要的类型实现它。例如:

trait CharCount {
    fn char_count(&self) -> usize;
}

impl CharCount for String {
    fn char_count(&self) -> usize {
        self.chars().count()
    }
}

有了这个特性,你可以编写你的通用方法来使用它:

fn say<T: CharCount>(msg: &T)  {
    let slen = msg.char_count();
    if slen > 0 {
        println!("Char count: {}", slen);
    } 
}

您可以调用saywith String,也可以使用决定实现该CharCount特征的任何其他类型,即使它是您在编写该特征时没有想到的类型。

于 2021-03-25T14:27:21.037 回答