我正在嘗試為 rust 迭代器實作 C 相鄰差異演算法。std::adjacent_different默認情況下,使用容器中的當前值減去其先前的值,例如,如果我們有[5, 7, 16],那么在 之后adjacent_difference,我們得到[5, 7-5, 16-7]
Iterator::Item - Iterator::Item我嘗試在 rust 中將其作為迭代器擴展,但發現std::ops::Sub::Output要使Iterator::next回傳型別快樂,我必須做一些奇怪的事情,比如Some(iter_item_value - <I as Iterator>::Item::default())獲得正確的型別godbolt
struct AdjacentDifference<I>
where I: Iterator
{
prev: Option<I::Item>,
it: I,
}
impl<I> Iterator for AdjacentDifference<I>
where I: Iterator, <I as Iterator>::Item: std::ops::Sub Default Copy,
{
type Item = <<I as Iterator>::Item as std::ops::Sub>::Output;
fn next(&mut self) -> Option<Self::Item> {
match (self.it.next(), self.prev) {
(None, _) => None,
(Some(i), Some(p)) => {
let r = i - p;
self.prev = Some(i);
Some(r)
}
(Some(i), None) => {
self.prev = Some(i);
Some(i - <I as Iterator>::Item::default()) // <<- really?
}
}
}
}
trait AdjacentDifferenceExt: Iterator where Self: Sized,
{
fn adjacent_difference(self) -> AdjacentDifference<Self>
where <Self as Iterator>::Item: Copy,
{
AdjacentDifference {
prev: None,
it: self,
}
}
}
impl<I> AdjacentDifferenceExt for I where I: Iterator {}
它有效,但我不太喜歡這段代碼,我這樣做完全錯了嗎?有沒有更好的方法來實作這一目標?
uj5u.com熱心網友回復:
有多種方法可以解決這個問題。
例如,一種選擇只是指定減法與元素本身具有相同的型別:
impl<I> Iterator for AdjacentDifference<I>
where
I: Iterator,
I::Item: std::ops::Sub<Output = I::Item> Copy,
{
type Item = <<I as Iterator>::Item as std::ops::Sub>::Output;
fn next(&mut self) -> Option<Self::Item> {
match (self.it.next(), self.prev) {
(None, _) => None,
(Some(i), Some(p)) => {
let r = i - p;
self.prev = Some(i);
Some(r)
}
(Some(i), None) => {
self.prev = Some(i);
Some(i)
}
}
}
}
這限制了您可以使用的型別(例如,您將無法使用Instant - Instant = Duration),但對于大多數型別來說,這是可以的。
另一種選擇是指定迭代器元素型別可以通過以下方式轉換為減法型別From:
impl<I> Iterator for AdjacentDifference<I>
where
I: Iterator,
I::Item: std::ops::Sub Copy,
<I::Item as std::ops::Sub>::Output: From<I::Item>,
{
type Item = <<I as Iterator>::Item as std::ops::Sub>::Output;
fn next(&mut self) -> Option<Self::Item> {
match (self.it.next(), self.prev) {
(None, _) => None,
(Some(i), Some(p)) => {
let r = i - p;
self.prev = Some(i);
Some(r)
}
(Some(i), None) => {
self.prev = Some(i);
Some(i.into())
}
}
}
}
這將隱含地適用于減法型別是元素型別的情況,這要歸功于毯子impl<T> From<T> for T。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/523848.html
標籤:C 算法锈迭代器
