我可以用来允许访问集合的中间元素的最一般特征是什么?
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>
,我们确实缩小了这个助手的用处。例如,不能传入 Range
s。也不能传入行为类似于向量的自定义数据类型。
我可以用来约束 elements
的最一般特征是什么,这样它就可以满足以下条件:
get_middle(vec![1, 2, 3])
// as well as...
get_middle(0..3)
我记得读到过可以将范围转换为切片,但事实似乎并非如此。将类型更改为 &[T]
会出错,并且尝试通过使用 <&[T]>::from(0..3)
强制转换来遵循其建议似乎不起作用。查看 Range
和 Vec
的文档,似乎 Index
特征是我想要的一半,但 len()
似乎没有特征.
你想要 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
将实现为随机访问。
我有一个辅助函数可以找到向量中的中间元素:
fn get_middle<T>(elements: Vec<T>) -> T {
elements[elements.len() / 2]
}
这允许我们像这样使用我们的助手:
get_middle(vec![1, 2, 3])
还有其他结构也可索引并具有长度。通过仅使用 Vec<T>
,我们确实缩小了这个助手的用处。例如,不能传入 Range
s。也不能传入行为类似于向量的自定义数据类型。
我可以用来约束 elements
的最一般特征是什么,这样它就可以满足以下条件:
get_middle(vec![1, 2, 3])
// as well as...
get_middle(0..3)
我记得读到过可以将范围转换为切片,但事实似乎并非如此。将类型更改为 &[T]
会出错,并且尝试通过使用 <&[T]>::from(0..3)
强制转换来遵循其建议似乎不起作用。查看 Range
和 Vec
的文档,似乎 Index
特征是我想要的一半,但 len()
似乎没有特征.
你想要 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
将实现为随机访问。