微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么在闭包中没有通过动态调度将值转换为特征对象?

如何解决为什么在闭包中没有通过动态调度将值转换为特征对象?

给出以下代码

use std::iter::Iterator;

trait Sequence {
    type SeqType: Iterator<Item = u32>;

    fn seq(&self) -> Option<Self::SeqType>;
}

struct Doubler<'a>(Option<&'a [u32]>);

impl<'a> Sequence for Doubler<'a> {
    type SeqType = Box<dyn Iterator<Item = u32>>;

    // NOT WORKING
    fn seq(&self) -> Option<Self::SeqType> {
        self.0
            .map(|v| Box::new(v.to_vec().into_iter().map(|x| x * 2)))
    }
}

fn print_seq<S: Sequence>(seq: S) {
    let v: Option<Vec<u32>> = seq.seq().map(|i| i.collect());
    println!("{:?}",v);
}

fn main() {
    let v = vec![1,2,3,4];
    print_seq(Doubler(Some(&v)));
}

编译器会抱怨:

error[E0308]: mismatched types
  --> src/main.rs:16:9
   |
15 |       fn seq(&self) -> Option<Self::SeqType> {
   |                        --------------------- expected `std::option::Option<std::Boxed::Box<(dyn std::iter::Iterator<Item = u32> + 'static)>>` because of return type
16 | /         self.0
17 | |             .map(|v| Box::new(v.to_vec().into_iter().map(|x| x * 2)))
   | |_____________________________________________________________________^ expected trait object `dyn std::iter::Iterator`,found struct `std::iter::Map`
   |
   = note: expected enum `std::option::Option<std::Boxed::Box<(dyn std::iter::Iterator<Item = u32> + 'static)>>`
              found enum `std::option::Option<std::Boxed::Box<std::iter::Map<std::vec::IntoIter<u32>,[closure@src/main.rs:17:58: 17:67]>>>`

但是它可以通过替换seq来实现:

fn seq(&self) -> Option<Self::SeqType> {
    fn convert(s: &[u32]) -> Box<dyn Iterator<Item = u32>> {
        Box::new(s.to_vec().into_iter().map(|x| x * 2))
    }
    self.0.map(convert)
}

可以here代码进行测试。

唯一的区别是在失败的示例中使用了闭包,而其他示例使用了(命名为?)函数,但是逻辑是相同的。似乎是一辈子的问题,但还没弄清楚。此外,Option::map应该会急切地消耗该值,然后应立即使用闭包。

为什么关闭示例失败?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。