簡體   English   中英

包裝返回迭代器的 function 時的生命周期問題

[英]Lifetime issue when wrapping a function returning an Iterator

我正在構建一個自定義數據結構,它應該為其元素返回一個迭代器。 如果簡化,它可能看起來像這樣:

use std::iter::{Iterator, StepBy};

// My collection which returns iterator to it's elements
pub trait MyCollection<'a, T: 'a> {
  type I: Iterator<Item = &'a T>;
  fn find_something(&'a self) -> Self::I;
}

現在,在某些情況下,我想為這個集合創建一個“包裝器”,用於轉換迭代器返回的元素。 為了這個例子,我們假設這個包裝器允許跳過原始迭代器的一些元素:

// Wrapper for a collection that allows iterating over elements with a step
pub struct StepWrapper<'a, A>(&'a A, usize);

impl<'a, T: 'a, A: MyCollection<'a, T>> MyCollection<'a, T> for StepWrapper<'a, A> {
  type I = StepBy<A::I>;
  fn find_something(&'a self) -> Self::I {
    self.0.find_something().step_by(self.1)
  }
}

// Function which takes a collection and a step value and returns a wrapped collection
fn wrap<'a, T: 'a, A: MyCollection<'a, T>>(a: &'a A, step: usize) -> impl MyCollection<'a, T> {
  StepWrapper(a, step)
}

不幸的是,嘗試使用此代碼時出現編譯錯誤:

// Example
impl<'a> MyCollection<'a, u64> for Vec<u64> {
  type I = std::slice::Iter<'a, u64>;
  fn find_something(&'a self) -> Self::I {
    return self.iter();
  }
}

fn main() {
  let collection = vec![12, 13, 14];
  let wrapped = wrap(&collection, 2);
  
  // Error now
  let result = wrapped.find_something().skip(1).next();
  //           ^^^^^^^ borrowed value does not live long enough

  println!("{}", result.unwrap());
}

我了解StepWrapper<'a, A>::find_something要求在與原始集合相同的生命周期內借用self 但是我所有將集合和包裝器的生命周期解耦的嘗試都是無用的。 本質上,包裝器中的find_something function 需要返回一個超過自身壽命的結果。 有沒有辦法用Rust來表達?

您正在使用的模式稱為流式迭代器,不幸的是,使用Iterator特征是不可能的。

這是 Rust 類型系統當前的一個弱點:它缺少所謂的泛型關聯類型或 GAT。 此語言功能有一個 RFC和一個跟蹤問題

同時, streaming_iterator crate旨在提供您正在尋找的功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM