在 Rust 中,如何组合两个相同的函数,但一个采用 Vec<String> 而另一个采用 Vec<&String>?
In Rust, how do I combine two functions that are identical, but one takes &Vec<String> and the other takes &Vec<&String>?
我一直在做代码的出现来学习 Rust,在第 3 天我写下了这个:
fn ones_per_bit(lines:&Vec<String>, bitcount:usize) -> Vec<u32> {
let mut out: Vec<u32> = Vec::new();
out.resize(bitcount, 0);
for line in lines {
for (i, c) in line.chars().enumerate() {
if c == '1' { out[i] += 1; }
}
}
return out;
}
然后是 copied/pasted,这样我就可以用 &Vec<&String>
而不是 &Vec<String>
来调用它。这行得通,但为了避免重复函数体,我希望使用泛型,但我天真的实现看起来像这样:
fn ones_per_bit<T>(lines:&Vec<T>, bitcount:usize) -> Vec<u32> {
let mut out: Vec<u32> = Vec::new();
out.resize(bitcount, 0);
for line in lines {
for (i, c) in line.chars().enumerate() {
if c == '1' { out[i] += 1; }
}
}
return out;
}
结果是:
error[E0599]: no method named `chars` found for reference `&T` in the current scope
--> main.rs:44:24
|
44 | for (i, c) in line.chars().enumerate() {
| ^^^^^ method not found in `&T`
所以我在这里漏掉了一个概念。我似乎需要告诉 Rust 在泛型类型上期望什么类型的方法,但我不确定最好的方法(或者如果有更好的语言特性我应该在这里使用)。
您在这里想要的是一种可以取消引用的类型 &str
。
这通常使用 <T: AsRef<str>>
通用约束来完成:
fn ones_per_bit<T: AsRef<str>>(lines: &[T], bitcount:usize) -> Vec<u32> {
let mut out: Vec<u32> = Vec::new();
out.resize(bitcount, 0);
for line in lines {
for (i, c) in line.as_ref().chars().enumerate() {
if c == '1' { out[i] += 1; }
}
}
return out;
}
旁注:将参数声明为 &[T]
而不是 &Vec[T]
以便它适用于 bot vec 引用和切片,这要归功于 deref coercion. See
我一直在做代码的出现来学习 Rust,在第 3 天我写下了这个:
fn ones_per_bit(lines:&Vec<String>, bitcount:usize) -> Vec<u32> {
let mut out: Vec<u32> = Vec::new();
out.resize(bitcount, 0);
for line in lines {
for (i, c) in line.chars().enumerate() {
if c == '1' { out[i] += 1; }
}
}
return out;
}
然后是 copied/pasted,这样我就可以用 &Vec<&String>
而不是 &Vec<String>
来调用它。这行得通,但为了避免重复函数体,我希望使用泛型,但我天真的实现看起来像这样:
fn ones_per_bit<T>(lines:&Vec<T>, bitcount:usize) -> Vec<u32> {
let mut out: Vec<u32> = Vec::new();
out.resize(bitcount, 0);
for line in lines {
for (i, c) in line.chars().enumerate() {
if c == '1' { out[i] += 1; }
}
}
return out;
}
结果是:
error[E0599]: no method named `chars` found for reference `&T` in the current scope
--> main.rs:44:24
|
44 | for (i, c) in line.chars().enumerate() {
| ^^^^^ method not found in `&T`
所以我在这里漏掉了一个概念。我似乎需要告诉 Rust 在泛型类型上期望什么类型的方法,但我不确定最好的方法(或者如果有更好的语言特性我应该在这里使用)。
您在这里想要的是一种可以取消引用的类型 &str
。
这通常使用 <T: AsRef<str>>
通用约束来完成:
fn ones_per_bit<T: AsRef<str>>(lines: &[T], bitcount:usize) -> Vec<u32> {
let mut out: Vec<u32> = Vec::new();
out.resize(bitcount, 0);
for line in lines {
for (i, c) in line.as_ref().chars().enumerate() {
if c == '1' { out[i] += 1; }
}
}
return out;
}
旁注:将参数声明为 &[T]
而不是 &Vec[T]
以便它适用于 bot vec 引用和切片,这要归功于 deref coercion. See