繁体   English   中英

如何编写带有`u32`或`&u32`的任何迭代器的通用函数?

[英]How to write a generic function taking any iterator of `u32` or `&u32`?

我正在尝试编写一个处理整数序列的函数。

fn process_one(n: u32) {}

fn process<II>(ii: II)
where
    II: IntoIterator<Item = u32>,
{
    for n in ii {
        process_one(n);
    }
}

我希望客户端能够传递Vec<u32>而不消耗它( process(&v) )。 无法使用此函数,因为<&Vec<u32> as IntoIterator>::Item&u32 我必须通过v.iter().cloned()来代替,这很烦人。

或者,我可以使绑定Item = &u32并使用process_one(*n) ,但随后我Item = &u32了相反的问题。

我试图想一种方法来一般地写这个,但我不知道如何。 据我所知, AsRefBorrowToOwnedDeref不起作用。

我需要的是一种写这个的方法:

fn process<II>(ii: II)
where
    II: IntoIterator<Item = MAGIC>, /* MORE MAGIC */
{
    for n in ii {
        process_one(MAGIC(n));
    }
}

以便所有这些编译:

fn test() {
    let v: Vec<u32> = vec![1, 2, 3, 4];
    process(&v);
    process(v);
    process(1..10);
}

我知道我可以使用自定义特征来做到这一点,但我觉得应该有一种没有所有样板的方法。

Borrow作品:

use std::borrow::Borrow;

fn main() {
    let x = vec![1, 2, 3];
    process(x.iter());
    process(x);
    process(1..3);
}

fn process_one(n: u32) {
    println!("{}", n)
}

fn process<I>(iter: I)
where
    I: IntoIterator,
    I::Item: Borrow<u32>,
{
    for x in iter {
        process_one(*x.borrow());
    }
}

这是我将如何使用自定义特征来做到这一点。

trait ToValue<V> {
    fn to_value(self) -> V;
}

impl<T> ToValue<T> for T {
    fn to_value(self) -> T {
        self
    }
}

impl<'a, T> ToValue<T> for &'a T
where
    T: Copy,
{
    fn to_value(self) -> T {
        *self
    }
}

fn process<N, II>(ii: II)
where
    II: IntoIterator<Item = N>,
    N: ToValue<u32>,
{
    for n in ii {
        process_one(n.to_value());
    }
}

虽然这解决了我的问题,但让我很不满意,我仍然认为应该有一个不涉及我自己特征的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM