簡體   English   中英

類型為 function 並具有返回壽命

[英]Type bound for a function with return lifetime

考慮 function

fn f(v: &[usize]) -> impl Iterator<Item = usize> + '_ {
    v.iter().cloned()
}

我想編寫一個通用的 function g ,它接受任何具有與f相同簽名的 function ,並調用具有不同生命周期的 function 。 這可能嗎?


我的嘗試1 :我天真地寫了

fn g<F>(f: F)
where
    F: for<'a> Fn(&'a [usize]) -> (impl Iterator<Item = usize> + 'a) {}

但我得到了

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return

我的嘗試 2 :我試圖給g特定迭代器類型的另一個類型參數:

fn g<F, I>(f: F)
where
    I: Iterator<Item = usize>,
    F: for<'a> Fn(&'a [usize]) -> I {}

我認為如果迭代器是'static ,這將起作用。 但在這種情況下, I需要成為具有一個生命周期參數的更高種類的類型。 具體來說,這個g編譯但不接受f


我的嘗試 3 :如上所述,但給g一個生命周期參數來專門化f

fn g<'a, F, I>(f: F)
where
    I: Iterator<Item = usize> + 'a,
    F: Fn(&'a [usize]) -> I {}

這編譯並接受f ,但g的主體只能使用具有特定生命周期'a f

正如 Sven Marnach 指出的那樣,它可以通過Box指針來完成。

fn f(v: &[usize]) -> Box<dyn Iterator<Item = usize> + '_> {
    Box::new(v.iter().cloned())
}

fn g<F>(f: F)
where
    F: Fn(&[usize]) -> Box<dyn Iterator<Item = usize> + '_>
{
    let v = vec![1, 2, 3];
    {
        let iter = f(&v);
        for i in iter {
            println!("{}", i);
        }
    }
}

fn main() {
    g(f)
}

基於這篇文章,我找到了一個使用輔助特征的原始界面(沒有Box )的解決方案:

fn f(v: &[usize]) -> impl Iterator<Item = usize> + '_ {
    v.iter().cloned()
}

trait Helper<'a> {
    type I: Iterator<Item = usize> + 'a;
    fn call(self, v: &'a [usize]) -> Self::I;
}
impl<'a, I, F> Helper<'a> for F
where
    I: Iterator<Item = usize> + 'a,
    F: Fn(&'a [usize]) -> I,
{
    type I = I;
    fn call(self, v: &'a [usize]) -> Self::I {
        self(v)
    }
}

fn g<F>(f: F)
where
    F: for<'a> Helper<'a>,
{
    let v = vec![1, 2, 3];
    {
        let iter = f.call(&v);
        for i in iter {
            println!("{}", i);
        }
    }
}

pub fn main() {
    g(f)
}

暫無
暫無

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

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