简体   繁体   English

返回值的生命周期与参数生命周期没有直接关系

[英]Lifetime of return value not directly related to parameter lifetime

I am new to rust, and having trouble figuring out the correct design pattern for what I am trying to do.我是 rust 的新手,并且无法为我正在尝试做的事情找出正确的设计模式。 In my program, there are Position structs, which reference a single coordinate system that they "belong" to.在我的程序中,有 Position 个结构,它们引用它们“属于”的单个坐标系。 I have understood that rust must therefore be able to guarantee that coordinate_system reference outlives the Position .据我所知, rust 因此必须能够保证coordinate_system参考比Position So far so good.到目前为止,一切都很好。

The issue is in a function such as transform_to_parent , where I want to create a new Position which is dependent on the lifetime of the exact coordinate_system that it later references, and not on the lifetime of the self parameter through which it accesses the coordinate system.问题出在 function 中,例如transform_to_parent ,我想在其中创建一个新的Position ,它取决于它后来引用的确切coordinate_system的生命周期,而不是它访问坐标系所通过的self参数的生命周期。 This seems to be the only thing that lifetime specifiers would allow.这似乎是生命周期说明符唯一允许的事情。

If I add a lifetime specifier to the following code, it compiles, but understandably complains when I let the old Position that I transformed from goes out of scope.如果我在下面的代码中添加一个生命周期说明符,它会编译,但是当我让我从 scope 中转换出来的旧 Position 消失时,可以理解地抱怨。

pub struct Position<'a> {
    // Position data omitted
    coordinate_system: &'a CoordinateSystem<'a>,
}

impl<'a> Position<'a> {
    fn transform_to_parent<'b>(self: &'b Self) -> Option<Position<'b>> {
        Some(Position {
            coordinate_system: self.coordinate_system.origin?.coordinate_system
        })
    }
}

pub struct CoordinateSystem<'a> {
    origin: Option<&'a Position<'a>>,
} 

// Test case
fn main() {
    // child_system is the child coordinate system of root_system, and has its origin at child_origin
    let root_system = CoordinateSystem { origin: None };
    let child_origin = Position { coordinate_system: &root_system };
    let child_system = CoordinateSystem { origin: Some(&child_origin) };

    let mut p2 = Position { coordinate_system: &child_system };
    {
        let p1 = Position { coordinate_system: &child_system };
        if let Some(x) = p1.transform_to_parent() { // Error: "borrowed value does not live long enough"
            p2 = x;
        }
    }
    // No-op, just pretend to use p2 again, after p1 has gone out of scope
    p2;
}

Is it possible for Rust to bind the lifetime of the function result to the lifetime of self.coordinate_system.get_origin()?.coordinate_system (ie the parent coordinate system), instead of the self ? Rust 是否可以将 function 结果的生命周期绑定到self.coordinate_system.get_origin()?.coordinate_system (即父坐标系)的生命周期,而不是self Is there a correct design pattern for something like this?这样的东西有正确的设计模式吗?

I assume that a ref-counting system would work, but I think that would be bad design, because there is clear ownership of the coordinate systems, and because the lifetime information should be deducible somehow .我假设引用计数系统会起作用,但我认为那将是糟糕的设计,因为坐标系有明确的所有权,而且生命周期信息应该可以以某种方式推导出来。

Just use the 'a lifetime from the field:只需使用'a一生”:

impl<'a> Position<'a> {
    fn transform_to_parent(&self) -> Option<Position<'a>> {
        Some(Position {
            coordinate_system: self.coordinate_system.origin?.coordinate_system
        })
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM