我正在尝试实现构建器功能:

extern crate debug;


use std::mem::size_of_val;


#[deriving(Show, PartialEq)]
pub struct A<'a> {
    pub a: &'a [i64],
    pub b: &'a str,
}


fn build<'a>() -> A<'a> {
    return A { a: &[1,2,3], b: "test" };
}


fn main() {
    let a = build();
    println!("{} - {} - `{:?}`", a, size_of_val(&a), a);
}

但这给了我下一个编译错误:
/prsrc/main.rs:16:20: 16:27 error: borrowed value does not live long enough
/prsrc/main.rs:16         return A { a: &[1,2,3], b: "test" };
                                         ^~~~~~~
/prsrc/main.rs:15:25: 17:2 note: reference must be valid for the lifetime 'a as defined on the block at 15:24...
/prsrc/main.rs:15     fn build<'a>() -> A<'a> {
/prsrc/main.rs:16         return A { a: &[1,2,3], b: "test" };
/prsrc/main.rs:17     }
/prsrc/main.rs:16:5: 16:41 note: ...but borrowed value is only valid for the statement at 16:4; consider using a `let` binding to increase its lifetime
/prsrc/main.rs:16         return A { a: &[1,2,3], b: "test" };
                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error

我什至尝试了A { a: [1,2,3], b: "test" }A { a: &'a [1,2,3], b: "test" }std:rc:Rc::new(A { a: &[1,2,3], b: "test" }),但仍然无法正常工作。

当我将&[i64]替换为Vec<i64>时:
fn build<'a>() -> A<'a> {
    return A { a: vec![1,2,3], b: "test" };
}

一切正常:
A { a: [1, 2, 3], b: test } - 40 - `A<'static>{a: collections::vec::Vec<i64>{len: 3u, cap: 4u, ptr: (0x7f1097426000 as *mut ())}, b: "test"}`

我有点困惑,因为据我所知,当我将&[i64]替换为&str时,str的实现应该类似于&[i64]Vec<i64>的工作。

那么如何实现切片的构建器功能呢?

最佳答案

您的一生中有问题的提示在这里:

fn build<'a>() -> A<'a> { /* ... */ }

您具有输出生存期,但没有输入生存期。

唯一可行的方法是,如果您的生命周期实际上是'static,否则它必须链接到至少一个定义它的参数。

因此,您的函数实际上应该是以下类型:
fn build() -> A<'static>

但是问题来了:您的两个引用必须链接到静态存储。真幸运,&str在这里是一种特殊情况。字符串文字(在您的情况下为"test")始终位于静态存储中。到目前为止,一切都很好。

但是&[1,2,3]不在静态存储中。实际上,此快捷方式等效于:
let temp = [1,2,3];
return A { a: &temp, b: "test" };

现在,生命周期问题变得很明显。

解决方法非常简单:将临时变量显式设置为'static,如下所示:
fn build() -> A<'static> {                    //'
    static temp: [i64, ..3] = [1,2,3];
    return A { a: &temp, b: "test" };
}

关于rust - 尝试在 rust 中实现工具构建器功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26512070/

10-10 04:54