我正在尝试实现构建器功能:
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/