生锈寿命说明符的问题
Problems with rust lifetime specifier
考虑以下程序:
fn func(source: &str, state: & Vec<&str>) {
println!("{}", source);
println!("{}", state[0]);
}
fn step<'a>(source: &'a str, state: &mut Vec<&'a str>) {
state.push(&source[4..10]);
func(source, state);
state.push(&source[4..10]);
}
fn main() {
let source = "abcdefghijklmnopqrstuvwxyz";
{
let mut state = Vec::<&str>::new();
step(source, &mut state);
step(source, &mut state);
step(source, &mut state);
}
}
这编译并且 运行s 没有错误。我完全可以理解为什么这里需要生命周期说明符 'a,否则你可以 运行:
fn main() {
let mut state = Vec::<&str>::new();
{
let source = "abcdefghijklmnopqrstuvwxyz";
step(source, &mut state);
step(source, &mut state);
step(source, &mut state);
}
println!("{}", state[0]);
}
这将导致未定义的输出。我的问题是我想将 "func" 的两个参数打包到一个结构中,但我无法完成这项工作:
struct MyStruct<'a, 'b> {
pub source: &'a str,
pub state: &'b mut Vec<&'b str>,
}
fn func(arg: MyStruct) {
println!("{}", arg.source);
println!("{}", arg.state[0]);
}
fn step<'a>(source: &'a str,
state: &mut Vec<&'a str>) {
state.push(&source[4..10]);
let s = MyStruct{source: source, state: state};
func(s);
state.push(&source[4..10]);
}
fn main() {
let source = "abcdefghijklmnopqrstuvwxyz";
{
let mut state = Vec::<&str>::new();
step(source, &mut state);
step(source, &mut state);
step(source, &mut state);
}
}
上面的代码没有编译错误信息:
107 | state: &mut Vec<&'a str>) {
| ----- consider changing the type of `state` to `&'a mut std::vec::Vec<&'a str>`
108 | state.push(&source[4..10]);
109 | let s = MyStruct{source: source, state: state};
| ^^^^^ lifetime `'a` required
如果我将状态状态更改为 &'a mut Vec<&'a str>,构建将失败并显示以下消息:
117 | step(source, &mut state);
| ----- first mutable borrow occurs here
118 | step(source, &mut state);
| ^^^^^ second mutable borrow occurs here
119 | step(source, &mut state);
120 | }
| - first borrow ends here
如果有人能告诉我如何完成这项工作,我将不胜感激。
注意:在这个示例程序中,"source" 是一个具有静态生命周期的字符串。在 "real" 程序中 "source" 没有静态生命周期,而是程序在 运行 时间内读取的文件内容。 "source" 寿命与 "state"
一样长或更长
你的函数参数中的生命周期情况是这样的:
fn step<'a>(source: &'a str,
state: &mut Vec<&'a str>)
让我们命名在生命周期中没有显式名称的引用:
fn step<'a, 'x>(source: &'a str,
state: &'x mut Vec<&'a str>)
在那里,现在所有的引用都有明确的生命周期,我们可以看到结构中的配置与它们在函数参数中的相互关系不对应。
如果您的结构应该遵循我们想要的相同关系:
struct MyStruct<'a: 'x, 'x> {
pub source: &'a str,
pub state: &'x mut Vec<&'a str>,
}
因为这是一个类型定义,我们需要添加隐含在函数中的关系 'a: 'x
“'a outlives 'x”
请记住,您还需要确定类型为 MyStruct 的 s
变量所持有的借用范围——它可变地借用状态(可变地意味着独占)。因此,您需要在 let s = ..
和 f(s)
行周围插入范围,以便 s
的范围在下一步调用之前结束:
{
let s = MyStruct{source: source, state: state};
func(s);
}
考虑以下程序:
fn func(source: &str, state: & Vec<&str>) {
println!("{}", source);
println!("{}", state[0]);
}
fn step<'a>(source: &'a str, state: &mut Vec<&'a str>) {
state.push(&source[4..10]);
func(source, state);
state.push(&source[4..10]);
}
fn main() {
let source = "abcdefghijklmnopqrstuvwxyz";
{
let mut state = Vec::<&str>::new();
step(source, &mut state);
step(source, &mut state);
step(source, &mut state);
}
}
这编译并且 运行s 没有错误。我完全可以理解为什么这里需要生命周期说明符 'a,否则你可以 运行:
fn main() {
let mut state = Vec::<&str>::new();
{
let source = "abcdefghijklmnopqrstuvwxyz";
step(source, &mut state);
step(source, &mut state);
step(source, &mut state);
}
println!("{}", state[0]);
}
这将导致未定义的输出。我的问题是我想将 "func" 的两个参数打包到一个结构中,但我无法完成这项工作:
struct MyStruct<'a, 'b> {
pub source: &'a str,
pub state: &'b mut Vec<&'b str>,
}
fn func(arg: MyStruct) {
println!("{}", arg.source);
println!("{}", arg.state[0]);
}
fn step<'a>(source: &'a str,
state: &mut Vec<&'a str>) {
state.push(&source[4..10]);
let s = MyStruct{source: source, state: state};
func(s);
state.push(&source[4..10]);
}
fn main() {
let source = "abcdefghijklmnopqrstuvwxyz";
{
let mut state = Vec::<&str>::new();
step(source, &mut state);
step(source, &mut state);
step(source, &mut state);
}
}
上面的代码没有编译错误信息:
107 | state: &mut Vec<&'a str>) {
| ----- consider changing the type of `state` to `&'a mut std::vec::Vec<&'a str>`
108 | state.push(&source[4..10]);
109 | let s = MyStruct{source: source, state: state};
| ^^^^^ lifetime `'a` required
如果我将状态状态更改为 &'a mut Vec<&'a str>,构建将失败并显示以下消息:
117 | step(source, &mut state);
| ----- first mutable borrow occurs here
118 | step(source, &mut state);
| ^^^^^ second mutable borrow occurs here
119 | step(source, &mut state);
120 | }
| - first borrow ends here
如果有人能告诉我如何完成这项工作,我将不胜感激。
注意:在这个示例程序中,"source" 是一个具有静态生命周期的字符串。在 "real" 程序中 "source" 没有静态生命周期,而是程序在 运行 时间内读取的文件内容。 "source" 寿命与 "state"
一样长或更长你的函数参数中的生命周期情况是这样的:
fn step<'a>(source: &'a str,
state: &mut Vec<&'a str>)
让我们命名在生命周期中没有显式名称的引用:
fn step<'a, 'x>(source: &'a str,
state: &'x mut Vec<&'a str>)
在那里,现在所有的引用都有明确的生命周期,我们可以看到结构中的配置与它们在函数参数中的相互关系不对应。
如果您的结构应该遵循我们想要的相同关系:
struct MyStruct<'a: 'x, 'x> {
pub source: &'a str,
pub state: &'x mut Vec<&'a str>,
}
因为这是一个类型定义,我们需要添加隐含在函数中的关系 'a: 'x
“'a outlives 'x”
请记住,您还需要确定类型为 MyStruct 的 s
变量所持有的借用范围——它可变地借用状态(可变地意味着独占)。因此,您需要在 let s = ..
和 f(s)
行周围插入范围,以便 s
的范围在下一步调用之前结束:
{
let s = MyStruct{source: source, state: state};
func(s);
}