为什么std :: mem :: drop`与特质范围较高的闭包| _ |()不完全相同?

问题描述 投票:4回答:1

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都是通用的,听起来“更通用”的签名Tfn(_) -> _不兼容是不合理的。为什么编译器在此处不接受for<'a> fn (&'a _) -> _的签名,而代之以抽水马桶盖来代替它,又有什么不同呢?

rust closures traits type-inference higher-kinded-types
1个回答
1
投票

但是,下面的代码显示drop与绑定在函数参数上的较高特质不兼容

这是因为您的高阶特征绑定指定了一个drop,它接受对FnOncereference,而T使用其参数。如果定义drop以使特征绑定实际上与foo的签名匹配,则可以将其应用于闭包和函数:

drop

旧的fn foo<F, T>(f: F, x: T) where F: FnOnce(T), { dbg!(f(x)); } 接受foo,因为Rust会根据用法推断出封闭的类型,并简单地生成一个接受引用的封闭,因此不是等效于|_| ()。如果您禁用此推断,例如通过首先将闭包存储到变量中,drop的调用将不会编译(foo)。两种情况下都会编译新定义。

© www.soinside.com 2019 - 2024. All rights reserved.