繁体   English   中英

生命周期问题,向结构添加函数指针

[英]Lifetime issue adding a function pointer to a struct

我试图添加一个指向结构的函数指针,却不知道该怎么做。 这是一个简单的示例:

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寿命足够长而没有将其作为g42_ure的参数g42_ure 对我而言,定义g42位置g42 (无论它位于impl Ureg42_ure()还是都不g42_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)),
            //         ^^^^^^^^^^^^^^^^^^
        }
    }   
    // ...
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM