如何在 Rust 结构中存储闭包?

San*_*jay 1 closures rust

struct User {
    id: i8,
    name: &'static str
}

struct UserMethods {
    add_user: Fn(User) -> (),
}

fn main() {
    UserMethods {
        add_user: |user| {

        }
    };
}
Run Code Online (Sandbox Code Playgroud)

编译器说,

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
Run Code Online (Sandbox Code Playgroud)

Sve*_*rev 5

Fn是一个特征,因此它是未定大小的。为了将它存储在结构体或变量中,您必须使用实现的东西,Sized否则编译器无法知道要分配多少内存。

有两种方法可以解决此问题:

  1. 使用泛型:
struct UserMethods<T: Fn(User)> {
    add_user: T,
}

fn main() {
    UserMethods {
        add_user: |user| {},
    };
}
Run Code Online (Sandbox Code Playgroud)
  1. 使用Box或任何其他智能指针:
struct UserMethods {
    add_user: Box<dyn Fn(User)>,
}

fn main() {
    UserMethods {
        add_user: Box::new(|user| {}),
    };
}
Run Code Online (Sandbox Code Playgroud)

您也可以使用普通函数指针(感谢@user2722968),但它不如闭包灵活(无法从环境中捕获任何内容):

struct UserMethods {
    add_user: fn(User),
}

fn main() {
    UserMethods {
        add_user: |user| {},
    };
}
Run Code Online (Sandbox Code Playgroud)

  • 第三种可能性(隐含在“通用”中)是使用简单的函数指针。即“fn(User)”而不是“Fn(User)”;`fn` 是 `Sized`,因为独立函数无法捕获它们的环境。 (2认同)