如何为不是函数参数的引用设置生命周期?

3

我正尝试编译这段代码。函数get_lines必须生成一个Line向量,将一个新行添加到其中并返回该向量。

fn main() {
    let begin_point = Point{x:100, y:100};
    let end_point = Point{x:300, y:100};

    let lines = get_lines( &begin_point, &end_point);
}

fn get_lines<'a>(begin_point: &'a Point, end_point: &'a Point) -> Vec<Line<'a>>
{
    let mut lines: Vec<Line> = vec![];
    let middle_color = Color{r:0,g:0,b:0};

    let line = Line {
        begin_point: begin_point,
        end_point: end_point,
        color: &middle_color,
    };

    lines.push(line);
    lines
}

struct Color<> {r:i32, g:i32, b:i32}
struct Point {x:i32, y:i32}
struct Line<'a> {
    begin_point: &'a Point,
    end_point: &'a Point,
    color: &'a Color
}

编译出现以下错误:
src\main.rs:16:17: 16:29 error: `middle_color` does not live long enough
src\main.rs:16         color: &middle_color,
                               ^~~~~~~~~~~~
src\main.rs:9:1: 21:2 note: reference must be valid for the lifetime 'a as defined on the block at 9:0...
src\main.rs: 9 {
src\main.rs:10     let mut lines: Vec<Line> = vec![];
src\main.rs:11     let middle_color = Color{r:0,g:0,b:0};
src\main.rs:12
src\main.rs:13     let line = Line {
src\main.rs:14         begin_point: begin_point,
               ...
src\main.rs:11:43: 21:2 note: ...but borrowed value is only valid for the block suffix following statement 1 at 11:42
src\main.rs:11     let middle_color = Color{r:0,g:0,b:0};
src\main.rs:12
src\main.rs:13     let line = Line {
src\main.rs:14         begin_point: begin_point,
src\main.rs:15         end_point: end_point,
src\main.rs:16         color: &middle_color,
               ...
error: aborting due to previous error

我该如何为不是函数参数的引用设置生命周期?或者代码逻辑有误吗?


你的问题可以被回答,但是最好知道你想要做什么。 - Tibor Benke
1个回答

3
你会收到错误提示,因为当get_lines()返回时,middle_color超出范围并被释放。如果不这样做,你将获得一个悬垂指针在向量中。
如果你真的想在Line中使用对color的引用,你可以在main函数中实例化它,并将其引用传递给get_lines(),例如:
fn get_lines<'a>(begin_point: &'a Point, end_point: &'a Point, middle_color: &'a Color) -> Vec<Line<'a>>
{
...
}

但是,如果您这样做,甚至可以在main中创建您的Line并将其移动到get_lines()中。

这不是完整的代码。我试图让它简单易懂。原始的 middle_color 是从其他函数中获取的。未来它将在循环中创建。这是完整的代码 - Haru Atari
1
在这种情况下,我不会在“Line”中使用引用,因为这样会失去很多灵活性。“Point”和“Color”是“Copy”类型,您只需要派生实现即可。所以我会让“Line”包含实际值。 - Tibor Benke
你的意思是什么?是创建Line的副本并将引用发送到该副本中的结构体吗?还是将Line结构体的字段作为实际值? - Haru Atari
1
后者 - 在Line的字段中使用实际值。例如:struct Line { p1: Point, p2:Point, c: Color} - Tibor Benke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接