繁体   English   中英

Rust 当结构方法创建的闭包采用对该结构的可变引用时的生命周期

[英]Rust lifetimes when closure created by struct method takes a mutable referece to that struct

我是 rust 的新手,尤其是嵌入式 rust。 我写了一些维护“警报系统”的东西,它可以处于各种定义的状态。 警报结构在转换到待命armed时,会设置一个带有关闭的 GPIO 引脚中断,该中断应该能够在触发时将警报的 state 设置为Alarm 编译器抱怨不能保证闭包不会超过结构。 我理解这个问题,但我不清楚如何解决它。

use crate::pins::CustomPin;
use sysfs_gpio::Pin;
#[derive(Debug)]
pub enum States {
    Disarmed,
    Armed,
    Alarm,
    Error,
}
pub struct Alarm {
    pub state: States,
    pub trigger_pin: Pin,
}
impl Alarm {
    pub fn arm(&mut self) -> () { // `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
        match self.trigger_pin.set_interrupt(Box::new(|| self.trigger())) { //...is captured and required to live as long as `'static` here
            Ok(_) => self.update(States::Armed),
            Err(_) => self.update(States::Error),
        };
    }
    pub fn disarm(&mut self) -> () {
        self.update(States::Disarmed);
    }
    pub fn trigger(&mut self) -> () {
        self.update(States::Alarm);
    }
    pub fn new(trigger_pin: u64) -> Alarm {
        let input = Pin::new(trigger_pin);
        Alarm {
            state: States::Disarmed,
            trigger_pin: input,
        }
    }
    fn update(&mut self, state: States) -> () {
        self.state = state;
    }
}

--

extern crate sysfs_gpio;
use sysfs_gpio::{Direction, Edge, Pin};
pub trait CustomPin {
    fn set_interrupt(&self, callback: Box<dyn Fn() -> ()>) -> sysfs_gpio::Result<()>;
}
impl CustomPin for Pin {
    fn set_interrupt(&self, callback: Box<dyn Fn() -> ()>) -> sysfs_gpio::Result<()> {
        self.with_exported(|| {
            self.set_direction(Direction::In)?;
            self.set_edge(Edge::FallingEdge)?;
            let mut poller = self.get_poller()?;
            loop {
                match poller.poll(1000)? {
                    Some(_) => callback(),
                    None => (),
                }
            }
        })
    }
}

我了解编译器消息,但我不知道如何修复它。 我考虑过RefCell ,但我的理解是,这将迫使警报与关闭一样长,而实际上,关闭不应该超过警报。

我想从根本上说,我不知道如何明确放弃该闭包。

您的问题是,除非另有明确说明,否则Box假定static生命周期。 因此,可以通过为特征定义显式生命周期参数来解决示例中的生命周期问题,例如:

pub trait CustomPin {
    fn set_interrupt<'a>(&self, callback: Box<dyn FnMut() -> () + 'a>) -> sysfs_gpio::Result<()>;
}

不幸的是,您的示例中有更多基本的所有权问题,借用检查器将拒绝。 您的基本问题是您从每个闭包中引用self ,尤其是从需要&mut self的函数中。 这总是会失败,您需要一个Rc或类似的构造来从多个位置引用相同的Alarm结构,遵循您可能从中迁移的“平均 C++ 构造”。

暂无
暂无

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

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