mar*_*nio 1 generics traits move-semantics rust
我正在尝试创建一个函数,该函数使用迭代器&[Vec<u64>]为i64每行中最大的一个返回元组“坐标”向量。我有它在具体类型上工作,但我希望它是通用的,T并且限制为可迭代类型。到目前为止我的代码:
fn find_largest_per_row<T>(input: &[T]) -> Vec<(usize, usize)>
where
T: IntoIterator<Item = u64>,
{
input
.iter()
.enumerate()
.map(|(r, v)| {
v.into_iter()
.enumerate()
.max_by_key(|&(_, v)| v)
.map(|(c, _)| (r, c))
.unwrap()
})
.collect::<Vec<_>>()
}
Run Code Online (Sandbox Code Playgroud)
我越来越:
fn find_largest_per_row<T>(input: &[T]) -> Vec<(usize, usize)>
where
T: IntoIterator<Item = u64>,
{
input
.iter()
.enumerate()
.map(|(r, v)| {
v.into_iter()
.enumerate()
.max_by_key(|&(_, v)| v)
.map(|(c, _)| (r, c))
.unwrap()
})
.collect::<Vec<_>>()
}
Run Code Online (Sandbox Code Playgroud)
我该如何解决?我意识到T是一个参考,所以我尝试了.cloned(),但这没有用。
另外,对于IntoIterator<Item=u64>,我需要指定u64还是可以提供更通用的东西?
IntoIterator::into_itertake self,这意味着它消耗(或移动)对象。
您已经添加了边界T: IntoIterator,因为这是唯一的边界,IntoIterator编译器将使用T的实现。调用into_iter上T会一直移动值,因为该功能只被给它一个参考,这是不正常T可能不是Copy-事实上,对于Vec这绝对不是。
但IntoIterator也为大多数对可迭代类型的引用而实现,例如&Vec<T>,其中的项也是引用。这些可以移动,因为引用是Copy,所以原始数据在移动时保持不变。
您可以像这样更改函数签名:
fn find_largest_per_row<'a, T>(input: &'a [T]) -> Vec<(usize, usize)>
where
&'a T: IntoIterator<Item = &'a u64>,
{
input
.iter()
.enumerate()
.map(|(r, v)| {
v.into_iter()
.enumerate()
.max_by_key(|&(_, v)| v)
.map(|(c, _)| (r, c))
.unwrap()
})
.collect::<Vec<_>>()
}
Run Code Online (Sandbox Code Playgroud)
要回答第二个问题,是的,您可以使项目通用。您可以省略它,然后指定代码所需的边界,而不是指定具体类型。您正在按值移动它,因此它需要是Copy(或者您需要更改代码以克隆它并Clone改为使用它),并且您正在使用max_by_key,这要求它是Ord. 函数签名将是:
fn find_largest_per_row<'a, T>(input: &'a [T]) -> Vec<(usize, usize)>
where
&'a T: IntoIterator,
<&'a T as IntoIterator>::Item: Ord + Copy,
Run Code Online (Sandbox Code Playgroud)
也可以看看:
| 归档时间: |
|
| 查看次数: |
48 次 |
| 最近记录: |