如何在Rust结构中存储闭包?
struct User {
id: i8,
name: &'static str
}
struct UserMethods {
add_user: Fn(User) -> (),
}
fn main() {
UserMethods {
add_user: |user| {
}
};
}
编译器说,
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
回答
Fn是一个特征,因此它是未定大小的。为了将它存储在结构体或变量中,您必须使用实现的东西,Sized否则编译器无法知道要分配多少内存。
有两种方法可以解决此问题:
- 使用泛型:
struct UserMethods<T: Fn(User)> {
add_user: T,
}
fn main() {
UserMethods {
add_user: |user| {},
};
}
- 使用
Box或任何其他智能指针:
struct UserMethods {
add_user: Box<dyn Fn(User)>,
}
fn main() {
UserMethods {
add_user: Box::new(|user| {}),
};
}
您也可以使用普通函数指针(感谢@user2722968),但它不如闭包灵活(无法从环境中捕获任何内容):
struct UserMethods {
add_user: fn(User),
}
fn main() {
UserMethods {
add_user: |user| {},
};
}
- The third possibility (which is implicit in the `generic`-one) is to use simple function pointers. That is, `fn(User)` instead of `Fn(User)`; `fn` is `Sized`, because free-standing functions can't capture their environment.