string - 如何在 Rust 中接受 Vec<String> 和 Vec<str> 作为函数参数

标签 string generics vector rust

我正在开发我的第一个 Rust crate,我想通过允许 foo(vec!["bar", "baz"]) 使我的 API 对用户更加友好。和 foo(vec![String::from("foo"), String::from("baz")]) .

到目前为止,我已经设法同时接受了 String&str但我正在努力为 Vec<T> 做同样的事情.

fn foo<S: Into<String>>(string: S) -> String {
    string.into()
}

fn foo_many<S: Into<String>>(strings: Vec<S>) -> Vec<String> {
    strings.iter().map(|s| s.into()).collect()
}

fn main() {
    println!("{}", foo(String::from("bar")));
    println!("{}", foo("baz"));

    for string in foo_many(vec!["foo", "bar"]) {
        println!("{}", string);
    }
}

我得到的编译器错误是:

error[E0277]: the trait bound `std::string::String: std::convert::From<&S>` is not satisfied
 --> src/main.rs:6:30
  |
6 |     strings.iter().map(|s| s.into()).collect()
  |                              ^^^^ the trait `std::convert::From<&S>` is not implemented for `std::string::String`
  |
  = help: consider adding a `where std::string::String: std::convert::From<&S>` bound
  = note: required because of the requirements on the impl of `std::convert::Into<std::string::String>` for `&S`

最佳答案

你可以选择完全通用,你不需要强制用户使用 Vec ,更好的是你可以采用实现 IntoIterator 的通用类型你只需要写下 Item实现 Into<String> ,语法有点奇怪和逻辑。您需要第二个通用类型来完成它。我调用I将成为迭代器的类型,T 是 Item 类型。

fn foo<S: Into<String>>(string: S) -> String {
    string.into()
}

fn foo_many<I, T>(iter: I) -> Vec<String>
where
    I: IntoIterator<Item = T>,
    T: Into<String>,
{
    iter.into_iter().map(Into::into).collect()
}

fn main() {
    println!("{}", foo(String::from("bar")));
    println!("{}", foo("baz"));

    for string in foo_many(vec!["foo", "bar"]) {
        println!("{}", string);
    }

    for string in foo_many(vec![foo("foo"), foo("baz")]) {
        println!("{}", string);
    }
}

这解决了您的问题并使您的函数更加通用。

关于string - 如何在 Rust 中接受 Vec<String> 和 Vec<str> 作为函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57223508/

相关文章:

c - 从 fgets() 输入中删除尾随换行符

java - ArrayList自己的类型转String?

java - private static <T> T cloneX(T x) - <T> 在这里表示什么?

c# - 为什么调用 ISet<dynamic>.Contains() 编译,但在运行时抛出异常?

java - 使用相同的参数类型创建通用映射来保存类型的键和值

c++ - 使用 std::accumulate 计算 vector 元素总和的最准确方法是什么?

python - 拆分不止一个空间?

c# - C# 中字符串的赋值和创建实例有什么区别?

loops - 从 Haskell 生成矢量代码?

c++ - 创建对象 vector 时,不唯一地为每个对象调用默认对象构造函数