std::mem::drop
的实现记录如下:
std::mem::drop
同样地,我希望闭包pub fn drop<T>(_x: T) { }
(俗称|_| ()
)在两个方向上都是对toilet closure的1:1替代。但是,下面的代码显示drop
与该函数的参数上绑定的较高特质不兼容,而抽水马桶则兼容。
drop
编译器的错误消息:
fn foo<F, T>(f: F, x: T)
where
for<'a> F: FnOnce(&'a T),
{
dbg!(f(&x));
}
fn main() {
foo(|_| (), "toilet closure"); // this compiles
foo(drop, "drop"); // this does not!
}
考虑到error[E0631]: type mismatch in function arguments
--> src/main.rs:10:5
|
1 | fn foo<F, T>(f: F, x: T)
| ---
2 | where
3 | for<'a> F: FnOnce(&'a T),
| ------------- required by this bound in `foo`
...
10 | foo(drop, "drop"); // this does not!
| ^^^
| |
| expected signature of `for<'a> fn(&'a _) -> _`
| found signature of `fn(_) -> _`
error[E0271]: type mismatch resolving `for<'a> <fn(_) {std::mem::drop::<_>} as std::ops::FnOnce<(&'a _,)>>::Output == ()`
--> src/main.rs:10:5
|
1 | fn foo<F, T>(f: F, x: T)
| ---
2 | where
3 | for<'a> F: FnOnce(&'a T),
| ------------- required by this bound in `foo`
...
10 | foo(drop, "drop"); // this does not!
| ^^^ expected bound lifetime parameter 'a, found concrete lifetime
对于任何大小的drop
都是通用的,听起来“更通用”的签名T
与fn(_) -> _
不兼容是不合理的。为什么编译器在此处不接受for<'a> fn (&'a _) -> _
的签名,而代之以抽水马桶盖来代替它,又有什么不同呢?
但是,下面的代码显示
drop
与绑定在函数参数上的较高特质不兼容
这是因为您的高阶特征绑定指定了一个drop
,它接受对FnOnce
的reference,而T
使用其参数。如果定义drop
以使特征绑定实际上与foo
的签名匹配,则可以将其应用于闭包和函数:
drop
旧的fn foo<F, T>(f: F, x: T)
where
F: FnOnce(T),
{
dbg!(f(x));
}
接受foo
,因为Rust会根据用法推断出封闭的类型,并简单地生成一个接受引用的封闭,因此不是等效于|_| ()
。如果您禁用此推断,例如通过首先将闭包存储到变量中,drop
的调用将不会编译(foo
)。两种情况下都会编译新定义。