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]`
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.
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.
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.
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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With