简体   繁体   中英

error to implement trait for function type in Rust

I want to implement the From trait for an enum. It's OK for usize , but fail for function type.

Is there any difference between usize and function type?

The code:

type Foo = fn (usize) -> usize;

enum Value {
    Number(usize),
    Function(Foo),
}

impl From<usize> for Value {
    fn from(n: usize) -> Self {
        Value::Number(n)
    }
}
impl From<Foo> for Value {
    fn from(f: Foo) -> Self {
        Value::Function(f)
    }
}

fn main() {
    let n: usize = 123;
    let vn: Value = n.into(); // OK for usize

    fn testf(n: usize) -> usize { n * n }
    let vf: Value = testf.into(); // fail for Foo
}

The error:

error[E0277]: the trait bound `Value: From<fn(usize) -> usize {testf}>` is not satisfied
  --> t.rs:24:27
   |
24 |     let vf: Value = testf.into(); // fail for Foo
   |                           ^^^^ the trait `From<fn(usize) -> usize {testf}>` is not implemented for `Value`
   |
   = help: the following implementations were found:
             <Value as From<fn(usize) -> usize>>
             <Value as From<usize>>
   = note: required because of the requirements on the impl of `Into<Value>` for `fn(usize) -> usize {testf}`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.

The error says that From<fn(usize) -> usize {testf}> is needed but only has From<fn(usize) -> usize> . I think the problem is {testf} , but I do not know why.

Thanks in advance

In Rust, function definitions does not have the fn type. They have a distinct, unnameable type that the compiler spells out as signature {name} , eg fn(usize) -> usize {testf} .

This type can be coerced , ie converted, to the corresponding fn type ( fn(usize) -> usize ), and usually it does so automatically, but when working with generics it does not.

You can force the compiler to coerce with as :

fn testf(n: usize) -> usize { n * n }
let vf: Value = (testf as fn(usize) -> usize).into();

Or by specifying the type explicitly:

fn testf(n: usize) -> usize { n * n }
let testf_fn: fn(usize) -> usize = testf;
let vf: Value = testf_fn.into();

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