yueruijie 发表于 2021-06-24 13:57
Tags:求教 如何从闭包中返回变量的引用 并且不产生悬垂指针
求教 如何从闭包中返回变量的引用 并且不产生悬垂指针!
感谢 苦瓜小仔 的认真回复。
用 Cow 这个智能指针, 它就是为你说的这种场景服务的。
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() }
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 _) }; }
悬垂指针产生的原因是引用指向的变量失效了,那么提升变量的生命周期让其变为static可以是一个解决办法,可以使用lazy_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 } ) }
评论区
写评论感谢 苦瓜小仔 的认真回复。
用
Cow
这个智能指针, 它就是为你说的这种场景服务的。它可以维持一个共享引用一直可用,由于是智能指针,直接利用 auto deref 就能使用到其内部的引用,而且在需要的时候转换为可变引用或者所有权的数据。
它是很基础的智能指针,所有基础类型和智能指针都与这个智能指针有关联,所以它非常强大和易用。
例子的话,参考前几天我给另一个问题回复的代码,也是闭包的:https://rustcc.cn/article?id=ee28ca6f-4f4d-486b-b1af-da0ea1b72862
悬垂指针产生的原因是引用指向的变量失效了,那么提升变量的生命周期让其变为static可以是一个解决办法,可以使用
lazy_static
这个包,实例如下: