Generics 如何在结构中存储闭包对象?

Generics 如何在结构中存储闭包对象?,generics,rust,closures,traits,trait-objects,Generics,Rust,Closures,Traits,Trait Objects,我不知道如何在结构中存储闭包对象。闭包对象的参数和返回是已知的。以下是我的简明代码: struct Instr<F> where F: Fn([i32;4],[i32;3]) -> [i32;4] { name: String, op: F } fn main() { // Simple example showing the difficulty: let tmp : Instr<Fn([i32;4],[i32;3]) ->

我不知道如何在结构中存储闭包对象。闭包对象的参数和返回是已知的。以下是我的简明代码:

struct Instr<F>
    where F: Fn([i32;4],[i32;3]) -> [i32;4]
{
    name: String,
    op: F
}

fn main()
{
    // Simple example showing the difficulty:
    let tmp : Instr<Fn([i32;4],[i32;3]) -> [i32;4]> = Instr { name: "asd".to_string(), op: |a,b| a};

    // What I really want is something more like this:
    // let instrs = vec![
    //     Instr { name: "asdf", op: |a,b| a },
    //     Instr { name: "qwer", op: |a,b| a }
    // ];
}

不同的闭包具有不同的大小,因此不能在结构中存储“原始闭包”或“原始特征对象”,它们必须位于指针后面,因此可以将它们放置在
框中,如下所示:

struct Instr{
名称:String,
op:Box[i32;4]>,,
}
fn main(){
让instrs=vec[
Instr{name:“asdf”.into(),op:Box::new(|a,b|a)},
Instr{name:“qwer”.into(),op:Box::new(|a,b|a)}
];
}

不同的闭包具有不同的大小,因此不能在结构中存储“原始闭包”或“原始特征对象”,它们必须位于指针后面,因此可以将它们放置在
框中,如下所示:

struct Instr{
名称:String,
op:Box[i32;4]>,,
}
fn main(){
让instrs=vec[
Instr{name:“asdf”.into(),op:Box::new(|a,b|a)},
Instr{name:“qwer”.into(),op:Box::new(|a,b|a)}
];
}

公认的答案完美地解决了您用例的解决方案,但我想澄清“未分级”错误消息和“简单示例”无法工作的原因

Rust能够按照问题中的定义将封盖存储在
仪表中,但您的类型规范将其混淆了。每个闭包的类型都是匿名的,不能命名。您试图通过拼写trait
Fn(ARGS…->RESULT
来指定闭包类型的做法是错误的,因为在Rust中,当您在预期类型的位置使用trait时,它引用了trait的动态实现,即。它是一个没有大小的trait对象,必须通过引用或智能指针来访问

因此,如果让Rust推断其类型,则可以创建一个包含任意闭包的
Instr

struct Instr<F>
    where F: Fn([i32;4],[i32;3]) -> [i32;4]
{
    name: String,
    op: F
}

fn main()
{
    // Simple example
    let tmp : Instr<_> = Instr { name: "asd".to_string(), op: |a,b| a};
}
struct Instr
其中F:Fn([i32;4],[i32;3])->[i32;4]
{
名称:String,
op:F
}
fn main()
{
//简单例子
设tmp:Instr=Instr{name:“asd”.to_string(),op:|a,b|a};
}

但是这不允许您创建一个
Instr
s的向量,每个向量都有不同的闭包,因为这些
Instr
s将有不同的类型。为此,您需要使用一个参考或一个
框,如接受的答案所示。

接受的答案完美地解决了您用例的解决方案,但我想澄清“未分级”错误消息和“简单示例”无法工作

Rust能够按照问题中的定义将封盖存储在
仪表中,但您的类型规范将其混淆了。每个闭包的类型都是匿名的,不能命名。您试图通过拼写trait
Fn(ARGS…->RESULT
来指定闭包类型的做法是错误的,因为在Rust中,当您在预期类型的位置使用trait时,它引用了trait的动态实现,即。它是一个没有大小的trait对象,必须通过引用或智能指针来访问

因此,如果让Rust推断其类型,则可以创建一个包含任意闭包的
Instr

struct Instr<F>
    where F: Fn([i32;4],[i32;3]) -> [i32;4]
{
    name: String,
    op: F
}

fn main()
{
    // Simple example
    let tmp : Instr<_> = Instr { name: "asd".to_string(), op: |a,b| a};
}
struct Instr
其中F:Fn([i32;4],[i32;3])->[i32;4]
{
名称:String,
op:F
}
fn main()
{
//简单例子
设tmp:Instr=Instr{name:“asd”.to_string(),op:|a,b|a};
}

但是这不允许您创建一个
Instr
s的向量,每个向量都有不同的闭包,因为这些
Instr
s将有不同的类型。为此,您需要使用一个参考或
框,如接受的答案所示。

谢谢,这正是我想要的。我正在学习生锈,我觉得在这个特殊的练习中涉水太深了。谢谢,这正是我想要的。我正在学习生锈,我认为在这个特殊的练习中涉入太深了。感谢你的回答。是时候读点书了…感谢你的回答。是时候读点书了。。。