Mar*_*rov 7 string generics vector rust
我的工作我的第一锈箱,我想使我的API有点允许双方友好用户更foo(vec!["bar", "baz"])和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);
}
}
Run Code Online (Sandbox Code Playgroud)
我得到的编译器错误是:
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`
Run Code Online (Sandbox Code Playgroud)
你可以选择完全通用,你不需要强迫用户使用 a Vec,更好的是你可以采用一个实现的泛型类型IntoIterator,你只需要编写该Item实现Into<String>,语法有点奇怪和逻辑。您需要第二个泛型类型来执行此操作。我I将迭代器的类型称为 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);
}
}
Run Code Online (Sandbox Code Playgroud)
这解决了您的问题并使您的功能更加通用。
这不起作用,因为您的迭代没有给您S但是&S.
如果要移动的串出矢量的,你必须让易变和漏吧:
fn foo_many<S: Into<String>>(mut strings: Vec<S>) -> Vec<String> {
strings.drain(..).map(|s| s.into()).collect()
}
Run Code Online (Sandbox Code Playgroud)