Tho*_*hel 4 lifetime rust borrow-checker
我想进入一个循环,n其中包含一个由函数借用的变量.在每一步,n取一个新的价值; 退出循环时,作业完成后,与其他变量的帮助,n将永远不会再被使用.
如果我不使用引用,我有这样的事情:
fn test(n: Thing) -> usize {
// stuff
let mut n = n;
for i in 1..10 {
let (q, m) = n.do_something(...);
n = m;
// stuff with x
}
x
}
Run Code Online (Sandbox Code Playgroud)
x一些与计算的结果q和m,但它是一个usize类型的,我没有遇到任何问题,在这部分代码.我没有测试这段代码,但这是个主意.我可以编写像这样的工作代码.
因为我想用引用来做; 我试着写:
fn test(n: &Thing) -> usize {
// stuff
let mut n = n;
for i in 1..10 {
let (q, m) = (*n).do_something(...);
n = &m;
// stuff with x
}
x
}
Run Code Online (Sandbox Code Playgroud)
现在代码将无法编译,因为m它的生命周期比n.我尝试通过做一些棘手的事情或克隆事情来使它工作,但这不是正确的方法.在C中,代码可以工作,因为我们不关心n在退出循环时指向什么,因为在循环之后n没有使用.我完全理解这是Rust和C不同的地方,但我很确定在Rust中这样做是一种干净的方式.
认为我的问题非常笼统; 我不要求对一些特设针对特定问题的解决方案.
正如Chris Emerson指出的那样,你所做的是不安全的,也可能不适合在C中编写类似的代码.在每次循环迭代结束时,您正在引用的变量超出范围,因此您将在下一次迭代开始时使用悬空指针.这将导致Rust试图阻止的所有内存错误; Rust阻止你做一些你认为安全的坏事.
如果你想要一些可以借用或拥有的东西; 那是一个Cow:
use std::borrow::Cow;
#[derive(Clone)]
struct Thing;
impl Thing {
fn do_something(&self) -> (usize, Thing) {
(1, Thing)
}
}
fn test(n: &Thing) -> usize {
let mut n = Cow::Borrowed(n);
let mut x = 0;
for _ in 1..10 {
let (q, m) = n.do_something();
n = Cow::Owned(m);
x = x + q;
}
x
}
fn main() {
println!("{}", test(&Thing));
}
Run Code Online (Sandbox Code Playgroud)
如果我理解正确的话,这个问题与循环之外的生活无关;而是与循环之外的生活有关。m生命周期不够长,无法为下一次迭代保留参考。
let mut n = n;
for i in 1..10 {
let (q,m) = (*n).do_something(...)
n = &m
} // At this point m is no longer live, i.e. doesn't live until the next iteration.
Run Code Online (Sandbox Code Playgroud)
同样,它取决于特定的类型/生命周期,但您可能会分配m给具有较长生命周期的变量,但随后您又回到了第一个示例。
| 归档时间: |
|
| 查看次数: |
2195 次 |
| 最近记录: |