You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust报错‘returns a value referencing data owned by the current function’求助

解决Rust中返回Svg时的临时值引用错误

你遇到的错误核心是Rust的生命周期规则:draw函数中,self.point()创建的Point是临时值,生命周期只局限于当前函数内部。而to_svg()方法会获取这个临时Point的引用,存入Svg的items向量中。当函数结束时,临时Point被销毁,Svg里的引用就变成了悬空引用,Rust会直接拒绝这种不安全的行为。

解决方案1:将Point绑定到Figure生命周期

因为第三方库的Svg依赖引用,我们需要让被引用的Point拥有足够长的生命周期——至少和返回的Svg一致。最直接的办法是把Point作为成员存储在Figure结构体中,让它的生命周期和Figure实例绑定:

fn main() {
    let a = Figure {
        a: 3,
        point: Point { p: 3 },
    };
    println!("result: {}", a.draw().to_svg_str());
}

struct Figure {
    a: i8,
    point: Point, // 添加Point成员,生命周期与Figure绑定
}

pub struct Svg<'a> {
    pub items: Vec<&'a dyn ToSvgStr>,
}

pub trait ToSvg {
    fn to_svg(&self) -> Svg;
}
impl<T: ToSvgStr> ToSvg for T {
    fn to_svg(&self) -> Svg {
        Svg { items: vec![self] }
    }
}

pub trait ToSvgStr {
    fn to_svg_str(&self) -> String;
}
impl<'a> ToSvgStr for Svg<'a> {
    fn to_svg_str(&self) -> String {
        String::from("abc")
    }
}

struct Point {
    p: i8,
}
impl ToSvgStr for Point {
    fn to_svg_str(&self) -> String {
        format!("p = {}", self.p)
    }
}

impl Figure {
    fn draw(&self) -> Svg {
        self.point.to_svg() // 引用Figure成员的Point,生命周期与self一致
    }
}

解决方案2:用堆存储管理生命周期(不修改Figure结构)

如果不想改动Figure的结构,可以用Box将Point放到堆上,同时通过自定义结构体持有Box和Svg,确保堆上对象的生命周期覆盖Svg的使用周期:

fn main() {
    let a = Figure { a: 3 };
    let owned_svg = a.draw();
    println!("result: {}", owned_svg.get_svg().to_svg_str());
}

struct Figure {
    a: i8,
}

pub struct Svg<'a> {
    pub items: Vec<&'a dyn ToSvgStr>,
}

pub trait ToSvg {
    fn to_svg(&self) -> Svg;
}
impl<T: ToSvgStr> ToSvg for T {
    fn to_svg(&self) -> Svg {
        Svg { items: vec![self] }
    }
}

pub trait ToSvgStr {
    fn to_svg_str(&self) -> String;
}
impl<'a> ToSvgStr for Svg<'a> {
    fn to_svg_str(&self) -> String {
        String::from("abc")
    }
}

struct Point {
    p: i8,
}
impl ToSvgStr for Point {
    fn to_svg_str(&self) -> String {
        format!("p = {}", self.p)
    }
}

// 自定义结构体,持有堆上的Point和对应的Svg
struct OwnedSvg {
    _point: Box<dyn ToSvgStr>,
    svg: Svg<'static>,
}

impl OwnedSvg {
    fn from_point(point: Point) -> Self {
        let boxed = Box::new(point);
        let svg = Svg { items: vec![&*boxed as &dyn ToSvgStr] };
        OwnedSvg { _point: boxed, svg }
    }

    fn get_svg(&self) -> &Svg {
        &self.svg
    }
}

impl Figure {
    fn point(&self) -> Point {
        Point { p: 3 }
    }
    fn draw(&self) -> OwnedSvg {
        OwnedSvg::from_point(self.point())
    }
}

内容的提问来源于stack exchange,提问作者Olivier Georg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 04:41:16