【问题标题】:Why does a boxed variable need an explicit type in order to be passed to a function? [duplicate]为什么装箱变量需要显式类型才能传递给函数? [复制]
【发布时间】:2019-12-24 19:07:28
【问题描述】:

为什么编译需要显式类型?我希望编译器能够理解Box<STest> 在第一个测试用例中等于Box<(dyn TTest + 'static)>,因为STest 实现了TTest 特征。是什么让编译器能够在第二种情况下将其隐式转换为 BoxedTTest,而在第一种情况下却不能这样做?

我在rustc 1.40.0(稳定)上使用rustc --edition 2018 mwe.rs 编译它,但--edition 2015rustc 1.42.0-nightly 上发生同样的错误。

trait TTest {}

struct STest {}
impl TTest for STest {}

type BoxedTTest = Box<dyn TTest>;

fn foo(_test: &BoxedTTest) {}

pub fn main() {
    // expected trait TTest, found struct `STest`
    let test1 = Box::new(STest {});
    foo(&test1);

    // OK
    let test2: BoxedTTest = Box::new(STest {});
    foo(&test2);
}

完整的错误如下:

error[E0308]: mismatched types
  --> mwe.rs:13:9
   |
13 |     foo(&test1);
   |         ^^^^^^ expected trait TTest, found struct `STest`
   |
   = note: expected type `&std::boxed::Box<(dyn TTest + 'static)>`
              found type `&std::boxed::Box<STest>`

【问题讨论】:

  • @Stargateur 似乎我有点搞砸了数据存储(因为我想存储任何在向量中实现 TTest 的东西)和处理数据之间的界限。让我尝试重构我的代码以将dyn TTest 带到任何地方,并且仅在与 Vec 交互时使用 Box'ed 版本。

标签: rust traits box


【解决方案1】:

在这种情况下,答案是不要像这样使用Box。正如 Stargateur 在 cmets 中所建议的,以下是要走的路:

trait TTest {}

struct STest {}
impl TTest for STest {}

fn foo(_test: &dyn TTest) {}

pub fn main() {
    // OK
    let test1 = STest {};
    foo(&test1);
}

如果您仍需要使用Box 将其存储在例如向量中,则应仅在严格需要时使用它:

fn add_test(test: Box<dyn TTest>) {
    let mut vec = vec!{};
    vec.push(test);
}
// ...
add_test(Box::new(test1));

【讨论】:

  • 请注意,在您的情况下,最好避免动态调度 play.rust-lang.org/… 我的评论只是“这里应该是要编译的代码”但是如果您的类型在编译时知道类型更好编译时调度
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-05
  • 2018-03-07
相关资源
最近更新 更多