元组结构到函数强制:所述函数的生命周期参数是什么?
Tuple struct to function coercion : what are the lifetime parameters of said function?
我不了解可以将元组结构强制转换为函数的功能,如:
struct MyType(u8);
let optional_mytype: Option<MyType> = Some(12).map(MyType);
// ^^^^^^ here, MyType is treated as a function
在上面的示例中,不涉及生命周期:一切都很简单。但是,当结构具有通用生命周期限制时,我在定义它将强制执行的函数的确切签名时遇到了麻烦。
这是我尝试做的事情的 MRE,但没有成功 (sandbox link):
struct MyStruct<'a>(&'a ());
// This looks, to me, like the signature the "constructor" should have
type MyStructConstructor = for<'a> fn(&'a ()) -> MyStruct<'a>;
/// Coercion problem here
fn some_code() {
let mut constructor: MyStructConstructor = MyStruct;
}
以及类型检查器给出的错误:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/lib.rs:7:48
|
7 | let mut constructor: MyStructConstructor = MyStruct;
| ^^^^^^^^ one type is more general than the other
|
= note: expected fn pointer `for<'a> fn(&'a ()) -> MyStruct<'a>`
found fn pointer `fn(&()) -> MyStruct<'_>`
老实说,我不明白为什么我的构造函数类型别名无效,以及为什么错误消息建议的类型比应有的松散得多。我的意思是,我的结构的生命周期 <'a>
应该完全等于结构中包含的单元引用的生命周期,而不是随机的。
Here 是我实际尝试做的一个更具体(仍然是最小)的示例,如果上下文对您有帮助的话。
提前致谢
事实上,错误消息可能有点误导。 '_
并不意味着任何一生,它只是意味着我没有明确命名的一生,就像写[=13] =](与 &'_ ()
相同)。 Rust 这样做是因为那不是问题所在。
为了理解,让我们在代码中实际注释隐式泛型生命周期:
fn some_code() {
let constructor: MyStructConstructor = MyStruct<'_>;
}
注意到哪里出了问题吗?在右边,你有一些东西,它的类型在整个生命周期都是通用的。在左边,你没有。
事实上,MyStruct
更合适的构造函数签名是
struct MyStruct<'a>(&'a ());
type MyStructConstructor<'a> = fn(&'a ()) -> MyStruct<'a>;
fn some_code() {
let constructor: MyStructConstructor = MyStruct;
}
隐式保留生命周期 — 参见 the playground。
这编译。
所以现在你可能明白为什么MyStructConstructor
比MyStruct
更通用了:因为对于MyStruct
,你必须指定生命周期开始,即实际类型是,对于给定的 'a
、MyStruct<'a>
。然后,使用该构造函数,您只能构建 MyStruct<'a>
类型的对象,给定 &'a ()
。另一方面,使用 MyStructConstructor
,给定一个生命周期为 any 的 ()
的引用,您将能够构建一个 MyStruct
一样的生命周期,比较通用
我不了解可以将元组结构强制转换为函数的功能,如:
struct MyType(u8);
let optional_mytype: Option<MyType> = Some(12).map(MyType);
// ^^^^^^ here, MyType is treated as a function
在上面的示例中,不涉及生命周期:一切都很简单。但是,当结构具有通用生命周期限制时,我在定义它将强制执行的函数的确切签名时遇到了麻烦。
这是我尝试做的事情的 MRE,但没有成功 (sandbox link):
struct MyStruct<'a>(&'a ());
// This looks, to me, like the signature the "constructor" should have
type MyStructConstructor = for<'a> fn(&'a ()) -> MyStruct<'a>;
/// Coercion problem here
fn some_code() {
let mut constructor: MyStructConstructor = MyStruct;
}
以及类型检查器给出的错误:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/lib.rs:7:48
|
7 | let mut constructor: MyStructConstructor = MyStruct;
| ^^^^^^^^ one type is more general than the other
|
= note: expected fn pointer `for<'a> fn(&'a ()) -> MyStruct<'a>`
found fn pointer `fn(&()) -> MyStruct<'_>`
老实说,我不明白为什么我的构造函数类型别名无效,以及为什么错误消息建议的类型比应有的松散得多。我的意思是,我的结构的生命周期 <'a>
应该完全等于结构中包含的单元引用的生命周期,而不是随机的。
Here 是我实际尝试做的一个更具体(仍然是最小)的示例,如果上下文对您有帮助的话。
提前致谢
事实上,错误消息可能有点误导。 '_
并不意味着任何一生,它只是意味着我没有明确命名的一生,就像写[=13] =](与 &'_ ()
相同)。 Rust 这样做是因为那不是问题所在。
为了理解,让我们在代码中实际注释隐式泛型生命周期:
fn some_code() {
let constructor: MyStructConstructor = MyStruct<'_>;
}
注意到哪里出了问题吗?在右边,你有一些东西,它的类型在整个生命周期都是通用的。在左边,你没有。
事实上,MyStruct
更合适的构造函数签名是
struct MyStruct<'a>(&'a ());
type MyStructConstructor<'a> = fn(&'a ()) -> MyStruct<'a>;
fn some_code() {
let constructor: MyStructConstructor = MyStruct;
}
隐式保留生命周期 — 参见 the playground。 这编译。
所以现在你可能明白为什么MyStructConstructor
比MyStruct
更通用了:因为对于MyStruct
,你必须指定生命周期开始,即实际类型是,对于给定的 'a
、MyStruct<'a>
。然后,使用该构造函数,您只能构建 MyStruct<'a>
类型的对象,给定 &'a ()
。另一方面,使用 MyStructConstructor
,给定一个生命周期为 any 的 ()
的引用,您将能够构建一个 MyStruct
一样的生命周期,比较通用