Reputation: 5131
struct User {
id: i8,
name: &'static str
}
struct UserMethods {
add_user: Fn(User) -> (),
}
fn main() {
UserMethods {
add_user: |user| {
}
};
}
The compiler says,
error[E0277]: the size for values of type `(dyn Fn(User) + 'static)` cannot be known at compilation time
--> src/main.rs:11:5
|
11 | / UserMethods {
12 | | add_user: |user| {},
13 | | };
| |_____^ doesn't have a size known at compile-time
Upvotes: 2
Views: 1280
Reputation: 27558
SvetlinZarev's second option only works if your closure is 'static
(it implies dyn Fn(User) + 'static
), if it's not you have to explicitly name the lifetimes, something like this:
struct UserMethods<'a> {
add_user: Box<dyn Fn(User) + 'a>,
}
fn main() {
let a = 99;
UserMethods {
add_user: Box::new(|user| { println!("{a}") }),
};
}
Upvotes: 0
Reputation: 15703
Fn
is a trait, thus it is unsized. In order to store it in a struct or variable, you must use something that implements Sized
otherwise the compiler cannot know how much memory to allocate.
There are two ways to fix the issue:
struct UserMethods<T: Fn(User)> {
add_user: T,
}
fn main() {
UserMethods {
add_user: |user| {},
};
}
Box
or any other smart pointer:struct UserMethods {
add_user: Box<dyn Fn(User)>,
}
fn main() {
UserMethods {
add_user: Box::new(|user| {}),
};
}
You can also use an ordinary function pointer (thanks @user2722968), but it's not as flexible as a closure (cannot capture anything from the environment):
struct UserMethods {
add_user: fn(User),
}
fn main() {
UserMethods {
add_user: |user| {},
};
}
Upvotes: 7