【问题标题】:How to solve lifetime inside for_each如何解决 for_each 中的生命周期
【发布时间】:2022-11-06 00:43:15
【问题描述】:

我尝试获取以下代码进行编译。 由于buffer,它希望插入更明确的生命周期。所以我尝试了,但仍然 还不知道如何使它也可以在for_each 中工作。

use std::{sync::mpsc::Sender, ffi::OsStr};

use inotify::{Event, EventMask, Inotify, WatchMask};

pub struct Watcher<'a> {
    buffer: [u8; 1024],
    sender: Sender<Event<&'a OsStr>>,
}

impl <'a> Watcher<'a> {
    pub fn new(sender: Sender<Event<&OsStr>>) -> Watcher{
        Watcher{
            buffer: [0; 1024],
            sender: sender,
        }
    }
    pub fn watch_for_led_directories(&mut self, dir: String) {
        let sender = self.sender.clone();
        let mut inotify = Inotify::init().expect("Error while initializing inotify instance");

        // Watch for modify and close events.
        inotify
            .add_watch(dir, WatchMask::CREATE | WatchMask::DELETE)
            .expect("Failed to add file watch");

        // Read events that were added with `add_watch` above.
        
        let events = inotify
            .read_events_blocking(&mut self.buffer)
            .expect("Error while reading events");

        events.filter(|e| -> bool { !e.mask.intersects(EventMask::ISDIR) }).for_each(|e| sender.send(e).unwrap());
    }
}

编辑:

我最终放弃了不复制字符串:

use std::{ffi::OsStr, sync::mpsc::Sender};

use inotify::{Event, EventMask, Inotify, WatchMask};

pub struct Watcher {
    buffer: [u8; 1024],
    sender: Sender<Event<String>>,
}

impl Watcher {
    pub fn new(sender: Sender<Event<String>>) -> Watcher {
        Watcher {
            buffer: [0; 1024],
            sender: sender,
        }
    }
    pub fn watch_for_led_directories(&mut self, dir: String) {
        let sender = self.sender.clone();
        let mut inotify = Inotify::init().expect("Error while initializing inotify instance");

        // Watch for modify and close events.
        inotify
            .add_watch(dir, WatchMask::CREATE | WatchMask::DELETE)
            .expect("Failed to add file watch");

        // Read events that were added with `add_watch` above.

        let events = inotify
            .read_events_blocking(&mut self.buffer)
            .expect("Error while reading events");

        let filter = |e: &Event<&OsStr>| -> bool {
            !e.mask.intersects(EventMask::ISDIR) || e.name.is_none()
        };
        events.filter(filter).for_each(|e| {
            sender
                .send(Event {
                    cookie: e.cookie,
                    mask: e.mask,
                    name: Some(e.name.unwrap().to_str().expect("Expected valid unicode string").into()),
                    wd: e.wd,
                })
                .unwrap()
        });
    }
}

【问题讨论】:

  • 你能包括确切的错误文本吗?

标签: rust


【解决方案1】:

如果您为self 添加生命周期,代码将编译:

pub fn watch_for_led_directories(&'a mut self, dir: String) {

这个问题可以用下面的代码来简化:

pub struct Struct1<'a> {
    str_value: &'a String,
    str_buffer: String,
}

fn add_to_string<'a>(s: &str, result: &'a mut String) -> &'a String {
    *result += s;
    result
}

impl <'a> Struct1 <'a> {
    pub fn new(s: &'a String) -> Self {
        Self {
            str_value: s,
            str_buffer: "".to_string(),
        }
    }

    pub fn func1(&mut self) {
        // This does not compile
        // self.str_value = add_to_string(self.str_value, &mut self.str_buffer);
    }

    pub fn func2(&'a mut self) {
        self.str_value = add_to_string(self.str_value, &mut self.str_buffer);
    }
}

换句话说,可变引用的生命周期默认情况下与其指向的对象的生命周期不同。

正如https://github.com/pretzelhammer/rust-blog/blob/master/posts/common-rust-lifetime-misconceptions.md 在第 5 节中描述的那样,func1 unelided 签名应如下所示:

impl <'a> Struct1 <'a> {
    pub fn func1<'b>func1<&'b mut self) {
    ...
    }
...
}

其中self.str_value 的生命周期为'a,而self.str_buffer 的生命周期为'b。因此存在不匹配,如果您将生命周期 'b 中的值分配给生命周期 'a 的结构属性,编译器不会让它通过。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-02
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    • 2021-01-03
    相关资源
    最近更新 更多