rust - 将函数指针添加到结构的生命周期问题

标签 rust

我正在尝试向结构添加函数指针,但不知道该怎么做。这是一个简单的例子:

struct Ure<'a> {
    num: u64,
    func: Option<&'a Fn(u64) -> u64>,
}

impl<'a> Ure<'a> {
    fn g42_ure(n: u64) -> Ure<'a> {
        Ure {
          num: n,
          func: Some(&Ure::g42),
        }
    }

    fn g42(u: u64) -> u64 {
        if u > 42 { u } else { 42 }
    }
}

这会导致以下错误:

error: borrowed value does not live long enough
  --> <anon>:10:23
   |
10 |           func: Some(&Ure::g42),
   |                       ^^^^^^^^ does not live long enough
11 |         }
12 |     }
   |     - temporary value only lives until here
   |
note: borrowed value must be valid for the lifetime 'a as defined on the body at 7:34...
  --> <anon>:7:35
   |
7  |       fn g42_ure(n: u64) -> Ure<'a> {
   |  ___________________________________^ starting here...
8  | |         Ure {
9  | |           num: n,
10 | |           func: Some(&Ure::g42),
11 | |         }
12 | |     }
   | |_____^ ...ending here

有没有办法在这个例子中获得对函数 g42 的引用,使其存活足够长的时间,而无需将其作为参数传递给 g42_ureg42 的定义位置对我来说并不重要(无论是在 impl Ureg42_ure() 还是两者都不在),而是来自一个OOP 背景在 impl Ure 中看起来更整洁。

我刚刚开始学习 Rust(并且非常喜欢它),所以任何帮助将不胜感激,谢谢。

最佳答案

Fn(u64) -> u64 类型不是函数指针,而是特征(-object)。 Rust 中的函数指针写成 fn(u64) -> u64,带有一个小写 f!另请注意,fn(u64) -> u64已经函数指针,无需再说&fn(u64) -> u64!

因此,使其工作的一种方法是使用函数指针 (Playground):

struct Ure {
    num: u64,
    func: Option<fn(u64) -> u64>,
    //           ^^^^^^^^^^^^^^
}

impl Ure {
    fn g42_ure(n: u64) -> Ure {
        Ure {
            num: n,
            func: Some(Ure::g42),
            //         ^^^^^^^^
        }
    }
    // ...
}

不过,函数指针有局限性。具体来说,他们不能拥有像闭包那样的环境。这就是 Fn 特性(连同它的兄弟 FnMutFnOnce)对一般可调用事物(包括函数指针和闭包)的抽象).

问题是您不能轻易使用特征对象。可能最简单的方法是使用 Box 在堆上存储和拥有一个特征对象。它看起来像这样(Playground):

struct Ure {
    num: u64,
    func: Option<Box<Fn(u64) -> u64>>,
    //           ^^^^^^^^^^^^^^^^^^^
}

impl Ure {
    fn g42_ure(n: u64) -> Ure {
        Ure {
            num: n,
            func: Some(Box::new(Ure::g42)),
            //         ^^^^^^^^^^^^^^^^^^
        }
    }   
    // ...
} 

关于rust - 将函数指针添加到结构的生命周期问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43694632/

相关文章:

rust - 如何在 Rust 中读取文本文件并读取每行多个值

rust - 从文件内容生成常量 ar 编译时间

enums - 我可以限制 Rust 枚举的大小吗?

multithreading - 在 Rust 中,线程中使用的所有内容都必须是 `Send` 吗?

rust - 如何创建一个服务于 API 并使用 Iron 回退到磁盘的服务器?

rust - 在 Rust 中创建一个连接 HashMap 键的字符串

rust - 我们可以修改成语周围的执行以使用可变的self吗?

multithreading - 使用 channel 在线程之间传递 Rust pnet 数据包

macos - MacOS 中的 WebView : How to request file system permissions correctly

rust - 函数参数的特征不匹配