首页 > 解决方案 > 我可以用来允许访问集合的中间元素的最一般特征是什么?

问题描述

我有一个辅助函数可以找到向量中的中间元素:

fn get_middle<T>(elements: Vec<T>) -> T {
    elements[elements.len() / 2]
}

这允许我们像这样使用我们的助手:

get_middle(vec![1, 2, 3])

还有其他结构也可索引并具有长度。通过仅使用Vec<T>. 例如,Ranges 不能被传入。也不能像向量一样自定义数据类型。

我可以用来约束的最一般的特征是什么elements,它允许以下内容:

get_middle(vec![1, 2, 3])
// as well as...
get_middle(0..3)

我记得读过可以将范围转换为切片,但情况似乎并非如此。将类型更改为&[T]给出错误,并尝试通过强制转换来遵循其建议<&[T]>::from(0..3)似乎不起作用。查看Rangeand的文档Vec,似乎该Index特征是我想要的一半,但似乎没有len().

标签: rusttraits

解决方案


你想要ExactSizeIteratorIntoIterator

fn get_middle<T, U>(elements: U) -> Option<T>
where
    U: IntoIterator<Item = T>,
    U::IntoIter: ExactSizeIterator,
{
    let mut it = elements.into_iter();
    let len = it.len();

    it.nth(len / 2)
}

fn main() {
    assert_eq!(get_middle(vec![1, 2, 3]), Some(2));
    assert_eq!(get_middle(0..3), Some(1));
}

请注意,nth如果迭代器的源支持它(例如,切片或范围),则它被实现为随机访问。


推荐阅读