Is it possible to 'downcast' a trait object in a closure argument?
我想调用一个函数指针,它本身将一个特征对象作为参数:
1 2 3 4 | fn invoke(x: &Fn(&WithFoo), y: &MyStruct) { // MyStruct implements WithFoo x(y); } |
到目前为止一切顺利。现在,我遇到的问题是如何使用带有签名的函数指针调用它,例如
这是我尝试执行此操作的示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | trait WithFoo { fn foo(&self); } trait WithFooBar: WithFoo { fn bar(&self); } struct MyStruct { } impl WithFoo for MyStruct { fn foo(&self) { println!("foo"); } } impl WithFooBar for MyStruct { fn bar(&self) { println!("bar"); } } fn foobar_caller(wf: &WithFooBar) { wf.foo(); wf.bar(); } fn invoke(x: &Fn(&WithFoo), y: &MyStruct) { x(y); } fn main() { let data = MyStruct {}; invoke(&foobar_caller,&data); } |
这会失败并出现以下编译错误:
1 | error: type mismatch: the type `fn(&WithFooBar) {foobar_caller}` implements the trait `for<'r> std::ops::Fn<(&'r WithFooBar + 'r,)>`, but the trait `for<'r> std::ops::Fn<(&'r WithFoo + 'r,)>` is required (expected trait `WithFoo`, found trait `WithFooBar`) [--explain E0281] |
我知道错误是说
是否有可能以某种方式将函数指针"向下转换"为类型
1 2 | let f = &foobar_caller as &Fn(&WithFoo); invoke(f,&data); |
还有这个:
1 2 | let f: &Fn(&WithFoo) = &foobar_caller; invoke(f,&data); |
但是这些尝试都不起作用。
(这个例子在 rust 的操场上。)
不,你不能这样做。首先,Rust 不支持将一个 trait 对象向下转换为另一个 trait 对象。使用
此外,您尝试做的事情并不合理:不应将期望接收