簡體   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