我有一个包含回调的结构:
struct MyStruct<F>
where
F: Fn(u32) -> u32,
{
cb: F,
}
impl<F> MyStruct<F>
where
F: Fn(u32) -> u32,
{
fn invoke(&self, val: u32) -> u32 {
(self.cb)(val)
}
}
fn callback(val: u32) -> u32 {
val + 1
}
fn main() {
let s = MyStruct { cb: callback };
s.invoke(0);
}
我想避免重复输入Fn(u32) -> u32
,特别是当它是一个更复杂的签名,或者我需要存储多个具有相同签名的回调时。有什么方法可以为特征绑定定义别名?我试图通过衍生特征来做到这一点,就像这样:
pub trait CallbackFn: Fn(u32) -> u32 {}
struct MyStruct<F>
where
F: CallbackFn,
{
cb: F,
}
impl<F> MyStruct<F>
where
F: CallbackFn,
{
fn invoke(&self, val: u32) -> u32 {
(self.cb)(val)
}
}
fn callback(val: u32) -> u32 {
val + 1
}
fn main() {
let s = MyStruct { cb: callback };
s.invoke(0);
}
但这无法编译:
error[E0277]: the trait bound `fn(u32) -> u32 {callback}: CallbackFn` is not satisfied
--> src/main.rs:24:13
|
24 | let s = MyStruct { cb: callback };
| ^^^^^^^^ the trait `CallbackFn` is not implemented for `fn(u32) -> u32 {callback}`
|
note: required by `MyStruct`
--> src/main.rs:3:1
|
3 | / struct MyStruct<F>
4 | | where
5 | | F: CallbackFn,
6 | | {
7 | | cb: F,
8 | | }
| |_^
error[E0599]: no method named `invoke` found for type `MyStruct<fn(u32) -> u32 {callback}>` in the current scope
--> src/main.rs:25:7
|
3 | / struct MyStruct<F>
4 | | where
5 | | F: CallbackFn,
6 | | {
7 | | cb: F,
8 | | }
| |_- method `invoke` not found for this
...
25 | s.invoke(0);
| ^^^^^^
|
= note: the method `invoke` exists but the following trait bounds were not satisfied:
`fn(u32) -> u32 {callback} : CallbackFn`
类型别名不能完全切掉它,因为它不允许传递闭包,而只是一个简单的函数指针-例如:
type F = fn(u32) -> u32;
struct MyStruct {
cb: F,
}
impl MyStruct {
fn invoke(&self, val: u32) -> u32 {
(self.cb)(val)
}
}
fn main() {
let s = MyStruct { cb: |x| x + 1 }; // works
let v = 5u32;
let t = MyStruct { cb: |x| (x + v) }; // fails
s.invoke(0);
t.invoke(1);
}