我可以用来允许访问集合的中间元素的最一般特征是什么?

What is the most general trait I can use to allow for accessing the middle element of a collection?

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

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) 强制转换来遵循其建议似乎不起作用。查看 RangeVec 的文档,似乎 Index 特征是我想要的一半,但 len() 似乎没有特征.

你想要 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 将实现为随机访问。