代码之家  ›  专栏  ›  技术社区  ›  user2138149

如何表达接受和返回引用的闭包的生存期约束?

  •  0
  • user2138149  · 技术社区  · 3 年前

    我有 sketched out an example problem in the Rust playground 。

    为了参考,我将在这个问题的末尾提供完整的代码。

    我试图编写以下函数。

    fn get_longest_time_window(&self) -> Option<u64> {
            
            let lambda = |lhs: &Element, rhs: &Element| -> &Element {
                
                return
                    if lhs.time_window >= rhs.time_window {
                        lhs
                    }
                    else {
                        rhs
                    }
            };
            
            let selected = self.data.iter().reduce(lambda);
    
            // ...
    

    此功能在 self.data 。我已经尝试对这个数据结构进行迭代,并对其应用reduce闭包。

    此闭包引用中的元素对 data ,并返回对其中一个的引用。返回的引用在迭代结束时仍然有效,因为内存中没有任何数据被删除或以其他方式更改,从而导致重新分配,从而使引用无效。

    selected 应包含 Option<&Element>

    上面的内容表明该代码应该是有效的,但它没有编译,因为闭包谈到了3个引用,并且不知道它们之间的相对寿命是多少。

    我会的 猜测 寿命应该都是一样的,但我不知道如何用Rust语法来表达。

    我试图写的内容有效吗?如果有效,可以做些什么来编译它?


    代码:

    use std::collections::BTreeSet;
    
    struct Element {
        
        pub data: String, // arbitrary
        pub time_window: u64,
    }
    
    struct Machine {
        
        data: BTreeSet<Element>
    }
    
    impl Machine {
    
        fn new() -> Machine {
            
            let machine = Machine {
                data: BTreeSet::new()
            };
            
            return machine;
        }
        
        fn get_longest_time_window(&self) -> Option<u64> {
            
            let lambda = |lhs: &Element, rhs: &Element| -> &Element {
                
                return
                    if lhs.time_window >= rhs.time_window {
                        lhs
                    }
                    else {
                        rhs
                    }
            };
            
            let selected = self.data.iter().reduce(lambda);
        
            return selected.map(|x| {x.time_window});
        }
    }
    
    
    fn main() {
    
        let machine = Machine::new();
        
        let max_time_window = machine.get_longest_time_window();
        
        println!("max_time_window = {:?}", max_time_window);
    }
    
    1 回复  |  直到 3 年前
        1
  •  0
  •   cafce25    3 年前

    在您的情况下,您并不真正需要闭包,因为它不会捕获任何环境,常规函数将起作用:

    fn get_longest_time_window(&self) -> Option<u64> {
        fn lambda<'a>(lhs: &'a Element, rhs: &'a Element) -> &'a Element {
            return if lhs.time_window >= rhs.time_window {
                lhs
            } else {
                rhs
            };
        }
        //…
    }
    

    一旦 closure_lifetime_binder 稳定或在夜间,您可以使用它们在闭包上指定相同的值:

    #![feature(closure_lifetime_binder)]
    //…
    let lambda = for<'a> |lhs: &'a Element, rhs: &'a Element| -> &'a Element { /* … */ };
    
    推荐文章