如何在 Box::<_>::new() 中指定 rust Box 类型

WiS*_*GaN 3 rust

奇怪的是,在下面的代码片段中,第二个函数可以编译,但第三个函数不能编译。

pub fn foo1(iter: Box<dyn Iterator<Item = u8>> ) -> Box<dyn Iterator<Item = u8>> {
      Box::new(iter.map(|n| n + 1)) 
} // This compiles

pub fn foo2(iter: Box<dyn Iterator<Item = u8>> ) -> Box<dyn Iterator<Item = u8>> {
    let a: Box::<dyn Iterator<Item = u8>> = Box::<_>::new(iter.map(|n| n + 1));
    a
} // This also compiles

pub fn foo3(iter: Box<dyn Iterator<Item = u8>> ) -> Box<dyn Iterator<Item = u8>> {
    let a: Box::<dyn Iterator<Item = u8>> = Box::<dyn Iterator<Item = u8>>::new(iter.map(|n| n + 1));
    a   
} // This does not compile
Run Code Online (Sandbox Code Playgroud)

我们应该如何Box::<_>::new在第三个函数中指定它才能编译,为什么?

操场

Cha*_*man 6

在第一个和第二个版本中,您调用的函数不是 <Box<dyn Iterator<Item = u8>>>::new(). 该函数需要T: Sized, 但是dyn Iterator: !Sized. 相反,您调用<Box<SomeConcreteType>>::new(),并将结果强制为Box<dyn Iterator<Item = u8>>

完全类型指定的版本是:

pub fn foo3(iter: Box<dyn Iterator<Item = u8>>) -> Box<dyn Iterator<Item = u8>> {
    let a: Box<dyn Iterator<Item = u8>> = Box::<
        std::iter::Map<
            Box<dyn Iterator<Item = u8>>, // The original iterator type
            _,                            // The callback type (cannot be named using stable Rust)
        >,
    >::new(iter.map(|n| n + 1))
        as Box<dyn Iterator<Item = u8>>;
    a
}
Run Code Online (Sandbox Code Playgroud)

  • @WiSaGaN 哦,是的,强制转换的地方有时会令人惊讶。虽然添加一个 `as _` [足以暗示编译器执行强制](https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2021&amp;gist=1a190a980d29454082f676c1071862ee) (这归结为复杂允许编译器执行强制转换的规则,以及不允许编译器执行强制转换的规则)。 (2认同)