我有以下类型签名的许多功能:
fn f() -> impl Fn(u32) -> u32 {
|x: u32| x
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能给它一个名字,Fn(u32) -> u32这样我就不必重复它了?尽管我可以做到type X = Fn(u32) -> u32;,但 Rust 不会让我使用它,因为它是一种类型而不是特征。我必须等待trait_alias还是可以做其他事情?
SCa*_*lla 11
你说得对。impl X需要X是一个特征,并且在特征别名登陆之前不可能有正确的特征别名。发生这种情况时,您将能够执行以下操作:
#![feature(trait_alias)]
trait X = Fn(u32) -> u32;
fn f() -> impl X {
|x: u32| x
}
Run Code Online (Sandbox Code Playgroud)
或者,当许可证IMPL特质类型别名的土地,你就可以做impl trait一个类型别名。不过,这略有不同。当我们使用 别名时type X = impl Trait,编译器将确保 的每个用法X实际上都是相同的具体类型。这意味着,在您的情况下,您将无法将它与多个不同的闭包一起使用,因为每个闭包都有自己独特的类型。
#![feature(type_alias_impl_trait)]
type X = impl Fn(u32) -> u32;
fn f() -> X {
|x: u32| x
}
Run Code Online (Sandbox Code Playgroud)
但是,这不会编译.
#![feature(type_alias_impl_trait)]
type X = impl Fn(u32) -> u32;
fn f() -> X {
|x: u32| x
}
// Even a closure with exactly the same form has a different type.
fn g() -> X {
|x: u32| x
}
Run Code Online (Sandbox Code Playgroud)
错误是
#![feature(trait_alias)]
trait X = Fn(u32) -> u32;
fn f() -> impl X {
|x: u32| x
}
Run Code Online (Sandbox Code Playgroud)
这与特征别名形成对比,特征别名将允许在每个返回 的函数中使用不同的具体类型impl TraitAlias。有关更多信息,请参阅引入此语法和一般存在类型的 RFC 。
在这两个功能之一出现之前,您可以通过本质上的 hack 获得与 trait 别名类似的行为。这个想法是创建一个新的特性,它本质上等同于原始特性,但名称更短。
// This trait is local to this crate,
// so we can implement it on any type we want.
trait ShortName: Fn(u32) -> u32 {}
// So let's go ahead and implement `ShortName`
// on any type that implements `Fn(u32) -> u32`.
impl<T: Fn(u32) -> u32> ShortName for T {}
// We can use `ShortName` to alias `Fn(u32) -> u32`.
fn f() -> impl ShortName {
|x: u32| x
}
// Moreover, the result of that can be used in places
// that expect `Fn(u32) -> u32`.
fn g<T: Fn(u32) -> u32>(x: &T) -> u32 {
x(6_u32)
}
fn main() {
// We only know that `x` implements `ShortName`,
let x = f();
// But we can still use `x` in `g`,
// which expects an `Fn(u32) -> u32` argument
let _ = g(&x);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1380 次 |
| 最近记录: |