Ale*_*ing 4 generics traits rust
我有以下代码:
struct Helper<F1: Fn()> {
f: F1,
}
struct User<F2: Fn()> {
h: Helper<F2>,
}
fn new_user<F3: Fn()>() -> User<F3> {
User {
// error: expected type parameter, found closure
h: Helper { f: || {} },
}
}
fn main(){}
Run Code Online (Sandbox Code Playgroud)
所以User
需要一个Helper<F1>
由 指定的 F1 类型User
,在这种情况下是由中的闭包new_user
。
此代码编译失败与错误expected type parameter, found closure
在new_user
。至于我已经明白(例如见这个链接),这是因为约束类型参数F3
上new_user
被调用者指定(或签名也许?),因此,虽然关闭实现Fn()
特质,它不能限制类型参数 F3 以匹配闭包的类型。相反,它new_user
应该适用于任何给定的F3
,而这显然不会。
所以我的问题是:我该如何解决这个问题?有没有表达,我想的任何方式new_user
返回一个User
与F2
set到闭包的类型吗?
我尝试使用类型推断占位符:
// error: the type placeholder `_` is not allowed within types on item signatures
fn new_user() -> User<_> {
User {
h: Helper { f: || {} },
}
}
Run Code Online (Sandbox Code Playgroud)
我可以使用 Box,但这需要修改Helper
,这在我的实际情况中并不理想:
struct Helper {
f: Box<dyn Fn()>,
}
struct User {
h: Helper,
}
fn new_user() -> User {
User {
h: Helper { f: Box::new(|| {}) },
}
}
fn main(){}
Run Code Online (Sandbox Code Playgroud)
我也在尝试Fn()
用自定义特征替换,我可以User
专门实现它,但到目前为止它很笨重。
有什么建议?
tl;博士; 你可能想要这个:
fn new_user() -> User<impl Fn()> {
User {
h: Helper { f: || {} },
}
}
Run Code Online (Sandbox Code Playgroud)
更多细节:让我们看看这个:
fn new_user<F3: Fn()>() -> User<F3> {
User {
// error: expected type parameter, found closure
h: Helper { f: || {} },
}
}
Run Code Online (Sandbox Code Playgroud)
这表明new_user
“接受”任何令人满意的Fn()
,但调用者在调用 时必须指定它new_user
。但是,要成功进行类型检查,提供的类型必须与 , 主体中使用new_user
的类型(即 的类型|| {}
)相同。但是,闭包具有匿名类型,因此 的调用者new_user
无法知道这种类型,因为它无法查看new_user
too的实现以找出为 提供什么F3
。
如前所述,您想要的是new_user
返回一个User<SomeConcreteType>
where SomeConcreteType
satisfies F3
。调用者不需要——事实上它甚至不应该——指定SomeConcreteType
,因为它是在new_user
. 您可以按如下方式执行此操作:
fn new_user() -> User<impl Fn()> {
User {
h: Helper { f: || {} },
}
}
Run Code Online (Sandbox Code Playgroud)
这样,您指定new_user
可以在没有任何参数的情况下调用,并且它返回User
具有满足Fn()
.
归档时间: |
|
查看次数: |
1515 次 |
最近记录: |