我遇到了写一个函数的困难,它需要将一个字符串集合作为参数。我的函数看起来像这样:
type StrList<'a> = Vec<&'a str>;
fn my_func(list: &StrList) {
for s in list {
println!("{}", s);
}
}
如果我将Vec<&'a str>
传递给函数,一切都很顺利,正如预期的那样。然而,如果我传递一个Vec<String>
,编译器会抱怨:
error[E0308]: mismatched types
--> src/main.rs:13:13
|
13 | my_func(&v2);
| ^^^ expected &str, found struct `std::string::String`
|
= note: expected type `&std::vec::Vec<&str>`
= note: found type `&std::vec::Vec<std::string::String>`
这是主要使用的内容:
fn main() {
let v1 = vec!["a", "b"];
let v2 = vec!["a".to_owned(), "b".to_owned()];
my_func(&v1);
my_func(&v2);
}
我的函数无法处理拥有字符串的向量。相反,如果我将StrList
类型改为:
type StrList = Vec<String>;
第一次调用失败,第二次成功。
一个可能的解决方案是从 v2
生成一个 Vec<&'a str>
,方法如下:
let v2_1 : Vec<_> = v2.iter().map(|s| s.as_ref()).collect();
但这对我来说似乎很奇怪。my_func
不应该关心字符串的所有权。
my_func
应该使用什么样的参数签名来支持拥有字符串的向量和字符串引用?
&[T]
有效吗?AsRef<str>
是清晰的。 - mbrt&[T]
,只是想知道为什么函数接受&[T]
,但main
传递的是&Vec<T>
,对吧?答案在于 deref 强制转换。因为&Vec<T>
比&[T]
更具体(你可以从很多不是向量的来源获得后者),所以推荐编写接受&[T]
而不是&Vec<T>
的函数。为了方便,foo(&vec)
会自动从向量构建切片。 - user395760