< 返回版块

yueruijie 发表于 2021-06-24 13:57

Tags:求教 如何从闭包中返回变量的引用 并且不产生悬垂指针

求教 如何从闭包中返回变量的引用 并且不产生悬垂指针!

评论区

写评论
Mike Tang 2021-06-24 23:06

感谢 苦瓜小仔 的认真回复。

苦瓜小仔 2021-06-24 21:08

Cow 这个智能指针, 它就是为你说的这种场景服务的。

它可以维持一个共享引用一直可用,由于是智能指针,直接利用 auto deref 就能使用到其内部的引用,而且在需要的时候转换为可变引用或者所有权的数据。

它是很基础的智能指针,所有基础类型和智能指针都与这个智能指针有关联,所以它非常强大和易用。

例子的话,参考前几天我给另一个问题回复的代码,也是闭包的:https://rustcc.cn/article?id=ee28ca6f-4f4d-486b-b1af-da0ea1b72862

use std::borrow::Cow;

fn main() {
    let s = concat("hello", "world"); // s: Cow<str>
    println!("{:?}", s);

    // 闭包
    let concat_str = |a: &'_ str, b: &'_ str| -> Cow<'_, str> { 
        let s = format!("{}/{}", a, b); // s: String
        s.into()
    };

    let s = concat_str("hello", "world"); // s: Cow<str>
    println!("{:?}", s);
}

// 函数
fn concat<'a>(a: &'a str, b: &'a str) -> Cow<'a, str> {
    let s = format!("{}/{}", a, b); // s: String
    s.into()
}
Bai-Jinlin 2021-06-24 19:07
fn main() {
    let a = || -> &mut _{ Box::leak(Box::new(vec![])) };
    let b = a();
    b.push(1);
    println!("{:?}", b);
    unsafe { Box::from_raw(b as *mut _) };
}
eweca-d 2021-06-24 15:41

悬垂指针产生的原因是引用指向的变量失效了,那么提升变量的生命周期让其变为static可以是一个解决办法,可以使用lazy_static这个包,实例如下:

#[macro_use]
extern crate lazy_static;

fn main() {
    let closure = produce_closure();
    let s: &String = closure();
    println!("The string in the closure is:{:?}", s);
}

fn produce_closure() -> Box<dyn Fn() -> &'static String> {
    Box::new(
        || {
            lazy_static! {
                static ref s: String = "hello".to_string();
            }

            &s
        }
    )
}
1 共 4 条评论, 1 页