【问题标题】:core::marker::Sized not implemented for Foocore::marker::Sized 未为 Foo 实现
【发布时间】:2015-09-07 21:53:43
【问题描述】:

我有这个相当简单的 Rust 程序:

use std::ops::Deref;

trait Foo {
  fn foo(&self);
}

impl Foo for () {
  fn foo(&self) {
    println!("hello world");
  }
}

impl<F> Foo for Box<F> where F: Foo {
  fn foo(&self) {
    let f: &F = self.deref();
    f.foo()
  }
}

fn call_foo<F>(foo: &F) where F: Foo {
  foo.foo()
}

fn main() {
  let foo: Box<Foo> = Box::new(());
  call_foo(&foo);
}

但我得到一个编译错误:

$ rustc main.rs
main.rs:26:3: 26:11 error: the trait `core::marker::Sized` is not implemented for the type `Foo` [E0277]
main.rs:26   call_foo(&foo);
             ^~~~~~~~
main.rs:26:3: 26:11 help: run `rustc --explain E0277` to see a detailed explanation
main.rs:26:3: 26:11 note: `Foo` does not have a constant size known at compile-time
main.rs:26   call_foo(&foo);
             ^~~~~~~~
main.rs:26:3: 26:11 note: required by `call_foo`
main.rs:26   call_foo(&foo);
             ^~~~~~~~
error: aborting due to previous error

E0277 的错误解释似乎无关。我该如何解决这个问题?

【问题讨论】:

  • 供将来参考:这个问题解决了我试图将盒装闭包从盒装闭包向量作为参数传递给函数的问题。在这个 rust 操场上找到我的代码:play.rust-lang.org/…

标签: rust traits


【解决方案1】:

当被问到这个问题时,错误消息并不明显。相同的代码 (Playground) 今天显示了更好的错误消息:

error[E0277]: the size for values of type `dyn Foo` cannot be known at compilation time
  --> src/main.rs:26:3
   |
26 |   call_foo(&foo);
   |   ^^^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `dyn Foo`
   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
   = note: required because of the requirements on the impl of `Foo` for `std::boxed::Box<dyn Foo>`
note: required by `call_foo`
  --> src/main.rs:20:1
   |
20 | fn call_foo<F>(foo: &F) where F: Foo {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

错误消息链接到 Rust 编程语言书,Chapter 19, section 4, "Dynamically sized types and the Sized trait"。 出现问题是因为默认情况下,泛型类型参数假定为Sized。但是,特征对象(Box&lt;dyn Foo&gt; 中的dyn Foo)没有已知的大小。在这种情况下这是可以接受的,所以我们修改了毯子实现以允许盒子大小未知:

impl<F: ?Sized> Foo for Box<F>
    where F: Foo

这里是固定代码,更新到 Rust 2018 版:

trait Foo {
    fn foo(&self);
}

impl Foo for () {
    fn foo(&self) {
        println!("hello world");
    }
}

impl<F: ?Sized> Foo for Box<F>
    where F: Foo
{
    fn foo(&self) {
        (**self).foo()
    }
}

fn call_foo<F>(foo: &F)
    where F: Foo
{
    foo.foo()
}

fn main() {
    let foo: Box<dyn Foo> = Box::new(());
    call_foo(&foo);
}

【讨论】:

  • 有趣,谢谢.. 遗憾的是,where F: Foo + ?Sized 不起作用。
  • @bfops 确实很伤心。这是我经常点击的more annoying bugs 之一;-)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-05
  • 2018-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-30
  • 1970-01-01
相关资源
最近更新 更多