【问题标题】:How to store a closure inside Rust struct?如何在 Rust 结构中存储闭包?
【发布时间】:2021-09-05 01:31:10
【问题描述】:
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

【问题讨论】:

    标签: rust closures


    【解决方案1】:

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

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

    1. 使用泛型:
    struct UserMethods<T: Fn(User)> {
        add_user: T,
    }
    
    fn main() {
        UserMethods {
            add_user: |user| {},
        };
    }
    
    1. 使用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| {},
        };
    }
    

    【讨论】:

    • 非常感谢您的回答。 fnFn 有何不同。你能解释一下吗?我读了几篇文章,但似乎无法理解它。
    • 第三种可能性(隐含在generic-one 中)是使用简单的函数指针。即fn(User)而不是Fn(User)fnSized,因为独立函数无法捕获它们的环境。
    • fn 是一个普通的函数指针,而Fn 是一个特征:stackoverflow.com/a/36390748/2588800
    猜你喜欢
    • 2015-03-06
    • 2020-07-18
    • 1970-01-01
    • 2017-04-19
    • 2021-04-21
    • 1970-01-01
    • 2015-06-08
    相关资源
    最近更新 更多