为什么我可以在结构的类型参数中编写函数类型?

Why am I able to write a function type in the type parameter of a struct?

如果我没理解错的话,在 Rust 中,每个闭包类型都有一个无法写出的唯一类型。我还认为这适用于函数,但是,我能够执行以下操作,其中我在 get_struct_1get_struct_2 的 return 类型中明确写入类型参数:

struct FooStruct<F>
where F: Fn(i32) -> i32
{
    f: F,
}

fn foo(x: i32) -> i32 {
    2*x
}

fn bar(x: i32) -> i32 {
    -1*x
}

fn get_struct_1() -> FooStruct<fn(i32) -> i32>
{
    FooStruct { f: foo }
}

fn get_struct_2() -> FooStruct<fn(i32) -> i32>
{
    FooStruct { f: bar }
}

// This does not work - the trait has to be boxed
//fn get_struct_3() -> FooStruct<Fn(i32) -> i32>
//{
//    FooStruct { f: |x| 10*x }
//}

fn main() {
    let mut x = get_struct_1();
    // Why does this work - do bar and foo have the same type?
    x = get_struct_2();
    // Why does this work - doesn't a closure have its own unique, unwriteable type?
    x = FooStruct { f: |x| 10*x };

    let mut y = FooStruct { f: |x| 10*x };
    // Does not work - no two closures have the same type.
    //y = FooStruct { f: |x| 10*x };
    // Does not work - even though the 'other way around' worked with x.
    // But _does_ work if I type-annotate y with FooStruct<fn(i32) -> i32>
    //y = get_struct_1();
}

我认为 Rust 在处理类型参数的方式上是单态的。所以如果我这样做

struct FooStruct {
    f: Box<dyn Fn(i32) -> i32>
}

程序会在 运行 时动态确定哪个 f 到 运行,但 FooStruct<F> 版本避免了动态调度。

这个例子似乎不同意这一点。如果 x = get_struct_2(); 行位于 if 语句内,编译器将无法确定 x 是否包含函数 foo 或 [=20= 的包装版本].

闭包(以及与此相关的函数)do 具有独特的、不可写的类型。但是,当它们不捕获任何变量时,也可以将它们(并且也隐式*)转换为函数指针,而您的变量则没有。这就是为什么它起作用的本质原因:

fn main() {
    // closure is inferred to be a function pointer
    let mut f: fn() -> i32 = || 5;
    // assigning a different function pointer
    f = || 6;
}

但事实并非如此:

fn main() {
    // closure is inferred to be a unique closure type
    let mut f = || 5;
    // uh oh! different closure type, errors
    f = || 6;
}

* 与其说是隐式转换不如说是隐式类型推断