core::marker::Sized not implemented for Foo

后端 未结 1 1640
名媛妹妹
名媛妹妹 2021-01-18 11:13

I have this fairly straightforward Rust program:

use std::ops::Deref;

trait Foo {
  fn foo(&self);
}

impl Foo for () {
  fn foo(&self) {
    printl         


        
相关标签:
1条回答
  • 2021-01-18 12:04

    The error message wasn't stellar when this question was asked. The same code (Playground) shows a better error message today:

    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 {
       | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    

    The error message links to The Rust Programming Language Book, Chapter 19, section 4, "Dynamically sized types and the Sized trait". The problem arises because by default, a generic type parameter is assumed to be Sized. However, a trait object (the dyn Foo in Box<dyn Foo>) does not have a known size. That's acceptable in this case, so we modify the blanket implementation to allow boxes things with an unknown size:

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

    Here is the fixed code, updated to the Rust 2018 edition:

    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);
    }
    
    0 讨论(0)
提交回复
热议问题