为什么我可以在结构的类型参数中编写函数类型?
Why am I able to write a function type in the type parameter of a struct?
如果我没理解错的话,在 Rust 中,每个闭包类型都有一个无法写出的唯一类型。我还认为这适用于函数,但是,我能够执行以下操作,其中我在 get_struct_1
和 get_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;
}
* 与其说是隐式转换不如说是隐式类型推断
如果我没理解错的话,在 Rust 中,每个闭包类型都有一个无法写出的唯一类型。我还认为这适用于函数,但是,我能够执行以下操作,其中我在 get_struct_1
和 get_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;
}
* 与其说是隐式转换不如说是隐式类型推断