Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a new associated function with a struct that has a closure member? [duplicate]

Tags:

rust

I almost have an intuitive sense of why this code should NOT work, but I can't quite put my finger on it. I think it has something to do with the fact that the new function would have a different return type every time.

Why is that a problem? Why does the direct creation work?

struct Struct<T>
where
    T: Fn(&[u8]),
{
    func: T,
}

impl<T> Struct<T>
where
    T: Fn(&[u8]),
{
    fn new() -> Struct<T> {
        // this doesn't work
        Struct { func: |msg| {} }
    }
}

fn main() {
    // this works
    let s = Struct { func: |msg| {} };
}

The error is

error[E0308]: mismatched types
  --> src/main.rs:14:24
   |
14 |         Struct { func: |msg| {} }
   |                        ^^^^^^^^ expected type parameter, found closure
   |
   = note: expected type `T`
              found type `[closure@src/main.rs:14:24: 14:32]`
like image 740
anderspitman Avatar asked Jan 06 '19 00:01

anderspitman


People also ask

How to access a member of a structure in C?

Structure members can be accessed by any function, anywhere in the scope of the Structure. Access Modifiers: C Programming language do not support access modifiers. So they cannot be used in C Structures.

What happens when a structure is passed by reference?

Passing structure by reference. The memory address of a structure variable is passed to function while passing it by reference. If structure is passed by reference, changes made to the structure variable inside function definition reflects in the originally passed structure variable.

How do you pass a structure to a function in C++?

C++ Structure and Function. In this article, you'll find relevant examples to pass structures as an argument to a function, and use them in your program. Structure variables can be passed to a function and returned in a similar way as normal arguments. A structure variable can be passed to a function in similar way as normal argument.

How to return structure from a function in C++?

Here's how you can return structure from a function: Here, the getInformation () function is called using s = getInformation (); statement. The function returns a structure of type struct student. The returned structure is displayed from the main () function. Notice that, the return type of getInformation () is also struct student.


1 Answers

tl;dr; You can do the following:

fn new() -> Struct<impl Fn(&[u8])> {
    Struct { func: |msg| {} }
}

More detailed:

Let's dissect your impl block:

impl<T> Struct<T>
where
    T: Fn(&[u8]),
{
    fn new() -> Struct<T> {
        // this doesn't work
        Struct { func: |msg| {} }
    }
}

We start with:

impl<T> Struct<T>
where
    T: Fn(&[u8]),

This tells the compiler that the whole impl block is "valid" for any T satisfying Fn(&[u8]).

Now:

fn new() -> Struct<T> {
    // this doesn't work
    Struct { func: |msg| {} }
}

You say that new returns a Struct<T>, and we are within the block stating that everything inside it works for any T satisfying Fn(&[u8]). However, you return one particular instance of Struct, namely the one parametrized by |msg| {} - thus, the return value can not be a Struct<T> for any T satisfying Fn(&[u8]).

However, you can modify it to do the following:

fn new() -> Struct<impl Fn(&[u8])> {
    Struct { func: |msg| {} }
}

This tells the compiler that new returns a Struct, whose parameter is known to satisfy Fn(&[u8]), so that the compiler should infer it. In particular it has no assumptions about T and returns one particular type.

In the direct initialization, however, we tell the compiler:

let s = Struct { func: |msg| {} };

The compiler sees that you want to create a Struct and knows that - in order to create it - it must infer the type for T res. func. It sees that you passed |msg| {} for func, infers the type for the closure and now knows a concrete type to put into the T.

like image 117
phimuemue Avatar answered Nov 15 '22 09:11

phimuemue