我有这个(最简化的)代码:
fn returns_closure() -> Box<dyn Fn(&u64)> {
let closure = |_| ();
Box::new(closure)
}
Run Code Online (Sandbox Code Playgroud)
这不会编译并带有相当无用的错误消息:
error[E0308]: mismatched types
--> src/main.rs:3:5
|
3 | Box::new(closure)
| ^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected type `FnOnce<(&u64,)>`
found type `FnOnce<(&u64,)>`
Run Code Online (Sandbox Code Playgroud)
但是,当我不先将闭包绑定到变量,而是直接在 Box 的构造函数中创建它时,它确实会编译:
error[E0308]: mismatched types
--> src/main.rs:3:5
|
3 | Box::new(closure)
| ^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected type `FnOnce<(&u64,)>`
found type `FnOnce<(&u64,)>`
Run Code Online (Sandbox Code Playgroud)
为什么第一个编译失败,两者有什么区别?
编辑:埃蒙斯的回答似乎是正确的。我用 nightly 工具链 (1.52.0) 编译了完全相同的代码,得到了一个更好的错误: …
我想创建一个抽象特征,它指定索引类型和值类型,其中实现该特征的任何结构都必须实现Index<IndexType>并IndexMut<IndexType>定义Output在实现该特征的每个结构中保持相同的类型。
我尝试创建一个特征,但似乎无法指定输出类型:
use std::ops::{Index, IndexMut};
struct Coord;
struct LightValue;
trait LightMap: Index<Coord> + IndexMut<Coord> {}
impl LightMap {
type Output = LightValue;
}
Run Code Online (Sandbox Code Playgroud)
warning: trait objects without an explicit `dyn` are deprecated
--> src/lib.rs:8:6
|
8 | impl LightMap {
| ^^^^^^^^ help: use `dyn`: `dyn LightMap`
|
= note: `#[warn(bare_trait_objects)]` on by default
error[E0191]: the value of the associated type `Output` (from the trait `std::ops::Index`) must be specified
--> src/lib.rs:8:6
|
8 | …Run Code Online (Sandbox Code Playgroud) fn main() {
let _ref_in_ref_out = |var: &i64| var;
}
Run Code Online (Sandbox Code Playgroud)
这不编译:
error: lifetime may not live long enough
--> src/main.rs:2:39
|
2 | let _ref_in_ref_out = |var: &i64| var;
| - - ^^^ returning this value requires that `'1` must outlive `'2`
| | |
| | return type of closure is &'2 i64
| let's call the lifetime of this reference `'1`
Run Code Online (Sandbox Code Playgroud)
显然,编译器推断出两个不同的生命周期(对于参数和返回类型),而不是相同。
是否可以编写一个闭包,使输入生命周期与输出生命周期相同?
就像是
error: lifetime may not live long enough
--> src/main.rs:2:39
|
2 | let _ref_in_ref_out …Run Code Online (Sandbox Code Playgroud)