use*_*861 3 function-pointers rust
我该如何克服这样的事情:
struct Test {
foo: Option<fn()>
}
impl Test {
fn new(&mut self) {
self.foo = Option::Some(self.a);
}
fn a(&self) { /* can use Test */ }
}
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
struct Test {
foo: Option<fn()>
}
impl Test {
fn new(&mut self) {
self.foo = Option::Some(self.a);
}
fn a(&self) { /* can use Test */ }
}
Run Code Online (Sandbox Code Playgroud)
如何从特征传递函数指针?类似于本例中会发生的情况:
impl Test {
fn new(&mut self) {
self.foo = Option::Some(a);
}
}
fn a() { /* can't use Test */ }
Run Code Online (Sandbox Code Playgroud)
您在这里尝试做的是从(这里使用 Python 术语,因为 Rust 没有这个词)绑定方法获取函数指针。你不能。
首先,因为 Rust 没有“绑定”方法的概念;.也就是说,您不能引用已绑定到位的调用者( 左侧的内容)的方法。如果你想构造一个近似于此的可调用函数,你可以使用闭包;IE || self.a()。
然而,这仍然行不通,因为闭包不是函数指针。没有像其他语言那样的可调用事物的“基本类型”。函数指针是一种单一的、特定的可调用类型;闭包完全不同。相反,有一些特征(在实现时)使类型可调用。它们是Fn、FnMut、 和FnOnce。因为它们是特征,所以您不能将它们用作类型,而必须从某个间接层后面使用它们,例如Box<FnOnce()>or &mut FnMut(i32) -> String。
现在,您可以更改Test为存储 an Option<Box<Fn()>>,但这仍然没有帮助。这是因为另一个问题:您试图在其内部存储对结构的引用。这不会起到很好的作用。如果您设法做到这一点,您实际上会导致该Test值永久无法使用。更有可能的是编译器不会让你走到这一步。
旁白:你可以做到这一点,但不能不诉诸引用计数和动态借用检查,这超出了这里的范围。
所以你所问问题的答案是:你不知道。
让我们改变一下问题:我们可以存储一个根本不尝试捕获调用者的可调用函数,而不是尝试插入自引用闭包。
struct Test {
foo: Option<Box<Fn(&Test)>>,
}
impl Test {
fn new() -> Test {
Test {
foo: Option::Some(Box::new(Self::a)),
}
}
fn a(&self) { /* can use Test */ }
fn invoke(&self) {
if let Some(f) = self.foo.as_ref() {
f(self);
}
}
}
fn main() {
let t = Test::new();
t.invoke();
}
Run Code Online (Sandbox Code Playgroud)
存储的可调用现在是一个显式调用调用者的函数,回避了循环引用的问题。Test::a我们可以通过将其称为自由函数来直接使用它来存储。另请注意,因为Test是实现类型,所以我也可以将其称为Self.
旁白:我还纠正了你的
Test::new功能。Rust 没有构造函数,只有像其他函数一样返回值的函数。
如果您确信自己永远不想将闭包存储在 中foo,则可以替换Box<Fn(&Test)>为fn(&Test)。这将您限制为函数指针,但避免了额外的分配。
如果您还没有阅读过Rust Book ,我强烈建议您阅读一下。
| 归档时间: |
|
| 查看次数: |
3782 次 |
| 最近记录: |