[英]Is there a trait that works for both VecDeque and Vec?
我們可以將Vec<f64>
傳遞給該函數,但不能傳遞VecDeque
,因為這是兩個切片:
fn mean(v: &[f64]) -> f64 {
let sum = v.iter().sum();
sum / v.len() as f64
}
是否有一個特征,可能類似於 C++ RandomAccessContainer
,允許我們編寫對Vec
和VecDeque
操作的代碼?
您可以只鏈接特征,例如Index<usize, Output = f64>
以獲取索引處的元素,以及IntoIterator<Item = &f64>
以使用IntoIterator
。 如果您需要len
,那么您可以創建自己的特征並實現它。
有2種方法:
fn mean(&[&[f64]]) -> f64
。 可以像mean(&[v.as_slice()])
一樣調用Iterator
。 我認為這是允許同時使用VecDeque
和Vec
最可接受的方式:use std::collections::VecDeque;
use std::iter::Iterator;
use std::vec::Vec;
fn mean<T: Iterator<Item = f64>>(iter: T) -> f64 {
let (last_index, sum) = iter
.enumerate()
.fold((0, 0.0), |(_, sum), (i, v)| (i, sum + v));
sum / (last_index as f64 + 1.0)
}
fn main() {
let v: Vec<f64> = vec![0.0, 1.0, 2.0, 3.0, 4.0];
println!("{:?}", mean(v.iter().copied()));
let v: VecDeque<f64> = v.into();
println!("{:?}", mean(v.iter().copied()));
}
在這些情況下,有一種值得考慮的替代方法,而不是尋找類型 A 和 B 都實現的可以傳遞給函數的特征,而是創建一個都支持的新特征,並改用新特征的功能。 它通常意味着一點點重復和樣板,但以后可以很好地擴展。
trait HasMeanF64 {
fn mean(&self) -> f64;
}
impl HasMeanF64 for &[f64] {
fn mean(&self) -> f64 {
self.iter().sum::<f64>() / self.len() as f64
}
}
impl HasMeanF64 for Vec<f64> {
fn mean(&self) -> f64 {
self.iter().sum::<f64>() / self.len() as f64
}
}
impl HasMeanF64 for VecDeque<f64> {
fn mean(&self) -> f64 {
self.iter().sum::<f64>() / self.len() as f64
}
}
現在你可以寫v.mean()
而不是寫mean(v)
v.mean()
。
如果你仍然想要你的mean(v)
形式,你可以寫
fn mean<T: HasMeanF64>(v: &T) -> f64 {
v.mean()
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.