简体   繁体   中英

Associated const to a trait in Rust not working as described in the tutorial

I am trying to execute the same code as described here

(Page ~448)

Playground

But when I try to execute this sample I get:

error[E0038]: the trait `Float` cannot be made into an object


--> src\main.rs:35:25
   |
35 |     let fibonacci_of_3: dyn Float = fibonacci(3);
   |                         ^^^^^^^^^ `Float` cannot be made into an object
   |
   = help: consider moving `ZERO` to another trait
   = help: consider moving `ONE` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
  --> src\maths.rs:4:11
   |
3  | pub trait Float {
   |           ----- this trait cannot be made into an object...
4  |     const ZERO: Self;
   |           ^^^^ ...because it contains this associated `const`
5  |     const ONE: Self;
   |           ^^^ ...because it contains this associated `const`

Here is the Fibonacci function:

pub fn fibonacci<T: Float + Add<Output=T>>(n: usize) -> T {
    match n {
        0 => T::ZERO,
        1 => T::ONE,
        n => fibonacci::<T>(n - 1) + fibonacci::<T>(n - 2),
    }
}

About the dyn, without it I get:

error[E0782]: trait objects must include the `dyn` keyword
  --> src\main.rs:34:25
   |
34 |     let fibonacci_of_3: Float = fibonacci(3);
   |                         ^^^^^
   |
help: add `dyn` keyword before this trait
   |
34 |     let fibonacci_of_3: dyn Float = fibonacci(3);
   |                         +++

Is the information outdated or am I doing something wrong?, in paper makes sense.

Regards

~M

You need to specify the types (not the trait itself) you want to use:

use std::ops::Add;

trait Float {
    const ZERO: Self;
    const ONE: Self;
}

impl Float for f32 {
    const ZERO: f32 = 0.0;
    const ONE: f32 = 1.0;
}

impl Float for f64 {
    const ZERO: f64 = 0.0;
    const ONE: f64 = 1.0;
}

fn fibonacci<T: Float + Add<Output=T>>(n: usize) -> T {
    match n {
        0 => T::ZERO,
        1 => T::ONE,
        n => fibonacci::<T>(n - 1) + fibonacci::<T>(n - 2),
    }
}

fn main() {
   let fibonacci_of_3: f32 = fibonacci::<f32>(3);
}

Playground

Notice that you can not use dyn Float . The compiler do not know how to build the vtable for that trait, as it do not have any methods at all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM