Generics 将泛型方法转化为特征对象安全方法

Generics 将泛型方法转化为特征对象安全方法,generics,rust,trait-objects,Generics,Rust,Trait Objects,我想制作一个适配器,删除通用参数(以生成一个trait对象),如下例所示 use std::ops::Deref; fn make_dyn_box<I, S>(iter_in: I) where I: Iterator<Item = S>, S: Deref<Target = u8>, { let mut iter_out = iter_in.map( |s| -> Box<dyn Deref<Tar

我想制作一个适配器,删除通用参数(以生成一个trait对象),如下例所示

use std::ops::Deref;

fn make_dyn_box<I, S>(iter_in: I)
where
    I: Iterator<Item = S>,
    S: Deref<Target = u8>,
{
    let mut iter_out = iter_in.map(
        |s| -> Box<dyn Deref<Target = u8>> {Box::new(s)}
    );
    take_dyn_box(&mut iter_out)
}

fn take_dyn_box<'a: 'b, 'b>(
    iter: &'a mut (dyn 'a + Iterator<Item = Box<dyn 'b + Deref<Target = u8>>>),
) { }
使用std::ops::Deref;
fn制造动力箱(国际热核聚变实验堆:I)
哪里
I:迭代器,
S:德里夫,
{
让mut iter_out=iter_in.map(
|s |->Box{Box::new(s)}
);
取出动力箱(&mut iter_)
}
fn take_dyn_box>),
) { }
有没有一种方法可以不用堆分配、只使用安全代码、不使用外部依赖项来实现这一点

下面是我想要的一个想法,但借阅检查不允许这样做

use std::ops::Deref;

fn make_dyn<I, S>(iter_in: I)
where
    I: Iterator<Item = S>,
    S: Deref<Target = u8>,
{
    let mut item = None;
    let item = &mut item;
    let mut iter_out = iter_in.map(|s| -> &dyn Deref<Target = u8> {
        item.replace(s);
        Option::as_ref(item).unwrap()
    });
    take_dyn(&mut iter_out)
}

fn take_dyn<'a: 'b, 'b>(
    iter: &'a mut (dyn 'a + Iterator<Item = &'b (dyn 'b + Deref<Target = u8>)>),
) { }
使用std::ops::Deref;
fn make_dyn(iter_in:I)
哪里
I:迭代器,
S:德里夫,
{
让mut item=None;
let item=&mut item;
让mut iter_out=iter_in.map(| s |->和dyn Deref{
项目.更换;
选项::as_ref(item).unwrap()
});
取出数据(&mut iter\u out)
}

fn take_dyn一种简单的方法是要求输入迭代器返回引用。这包括:

fn make_dyn<'b, I, S>(iter_in: I)
where
    I: Iterator<Item = &'b S>,
    S: Deref<Target = u8> + 'b,
{
    let mut iter_out = iter_in.map(|s| -> &dyn Deref<Target = u8> {
        s as _
    });
    
    take_dyn(&mut iter_out)
}

fn take_dyn<'a: 'b, 'b>(
    _iter: &'a mut (dyn 'a + Iterator<Item = &'b (dyn 'b + Deref<Target = u8>)>),
) { }
fn make\u dyn,
S:Deref+'b,
{
让mut iter_out=iter_in.map(| s |->和dyn Deref{
s作为_
});
取出数据(&mut iter\u out)
}
fn take_dyn,
S:Deref+'b,
{
iter|u in.map(|s |->和dyn Deref){
s作为_
})
}
(您还可以将其定义为实现<代码>迭代器特性的通用结构。)

现在:如果您不想要求输入迭代器返回引用,那么就无法返回新的迭代器

您在示例代码中所做的是在迭代器中创建一个小缓冲区,并返回对它的引用

如果该缓冲区存储在迭代器结构中,则尝试创建的内容称为流迭代器,当前无法实现。解释原因;从本质上讲,它需要对Rust的类型系统进行大而复杂的扩展

如果重新排列代码,让用户将闭包传递到函数中,则可以执行类似的操作。然后控制何时调用闭包,以便将返回的值存储到缓冲区中,并将对缓冲区的引用传递到闭包中。但这并不像通常的
Iterator
界面那样符合人体工程学


这是您使用示例代码所做的工作。。。我不太清楚它为什么不起作用。如果您将take_dyn更改为单个
&'b(dyn'b+Deref)>
,并重复调用它,那么它应该可以工作。

当您说“adapter”时,您的具体意思是迭代器适配器吗?如果您可以获取一个引用迭代器,那么这就是。但是,如果你有一个迭代器,它拥有它所迭代的值(或者更准确地说,它产生了自己的值),你可能必须创建一个自定义迭代器,以某种方式至少存储每个产生的值,但产生trait对象(作为引用);这很有帮助。