代码之家  ›  专栏  ›  技术社区  ›  Bailey Parker

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

  •  3
  • Bailey Parker  · 技术社区  · 6 年前

    我有一个helper函数,它在向量中查找中间元素:

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

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

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

    还有其他结构也是可转位的,并且有一个长度。我们只通过与 Vec<T> . 例如, Range 不能传进来。行为类似于向量的自定义数据类型也不能。

    什么是我可以用来约束的最一般的特质? elements 这样就可以做到:

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

    我记得有人读过这样的文章:范围可以被划分成片,但事实似乎并非如此。将类型更改为 &[T] 给出了一个错误,并尝试按照它的建议铸造 <&[T]>::from(0..3) 好像没用。查看文档 范围 Vec ,看起来 Index 特质是我想要的一半,但似乎并不是一种特质。 len() .

    1 回复  |  直到 6 年前
        1
  •  4
  •   Boiethios    6 年前

    你想要 ExactSizeIterator 具有 IntoIterator :

    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 如果迭代器的源支持它(例如,切片或范围),则实现为随机访问。