前几天,有一个问题,如果有人有一个问题,一个可变引用其中包含借来的数据本身就是一种类型的连接寿命.问题是提供对类型的引用,借用与类型内部借用数据相同的生命周期.我试图重新创建问题:
struct VecRef<'a>(&'a Vec<u8>);
struct VecRefRef<'a>(&'a mut VecRef<'a>);
fn main() {
let v = vec![8u8, 9, 10];
let mut ref_v = VecRef(&v);
create(&mut ref_v);
}
fn create<'b, 'a>(r: &'b mut VecRef<'a>) {
VecRefRef(r);
}
Run Code Online (Sandbox Code Playgroud)
我'b在这里明确注释了create().这不编译:
error[E0623]: lifetime mismatch
--> src/main.rs:12:15
|
11 | fn create<'b, 'a>(r: &'b mut VecRef<'a>) {
| ------------------
| |
| these two types are declared with different lifetimes...
12 | VecRefRef(r);
| ^ ...but data from `r` flows …Run Code Online (Sandbox Code Playgroud) 此代码在let c = a;编译错误"使用移动值:a"时按预期失败:
fn main() {
let a: &mut i32 = &mut 0;
let b = a;
let c = a;
}
Run Code Online (Sandbox Code Playgroud)
a被移入b并且不再可用于c的赋值.到现在为止还挺好.
但是,如果我只注释其b类型并将其他所有内容留下:
fn main() {
let a: &mut i32 = &mut 0;
let b: &mut i32 = a;
let c = a;
}
Run Code Online (Sandbox Code Playgroud)
代码再次失败 let c = a;
但这一次有一个非常不同的错误信息:"不能搬出去,a因为它是借来的......借来的*a发生在这里:let b: &mut i32 = a;"
所以,如果我只是注释b的类型:没有a进入b,而是一个"重新"的借用*a?
我错过了什么?
干杯.
fn main() {
let mut name = String::from("Charlie");
let x = &mut name;
let y = x; // x has been moved
say_hello(y);
say_hello(y); // but y has not been moved, it is still usable
change_string(y);
change_string(y);
}
fn say_hello(s: &str) {
println!("Hello {}", s);
}
fn change_string(s: &mut String) {
s.push_str(" Brown");
}
Run Code Online (Sandbox Code Playgroud)
当我分配x到y x已被移动。但是,当我在函数中使用它时,我希望可以移动具有移动语义的东西。但是,我仍然可以在后续调用后使用参考。也许这与 say_hello() 接受不可变引用有关,但 change_string() 接受可变引用但引用仍未移动。
我正在学习Rust,我遇到了一些令人困惑的行为.以下代码编译正常并按预期工作(编辑:添加除测试函数以外的代码,之前省略):
struct Container<'a> {
contents : &'a mut i32,
}
fn main() {
let mut one = Container { contents: &mut 5 };
test(&mut one);
println!("Contents: {}",one.contents);
}
fn test<'a>(mut x : &'a mut Container) {
*x.contents += 1;
let y = x;
*y.contents += 1;
x = y;
println!("{:?}",*x.contents)
}
Run Code Online (Sandbox Code Playgroud)
现在在声明中
let y = x;
Run Code Online (Sandbox Code Playgroud)
推断出类型.因为x是类型&'a mut Container,我认为这是等价的:
let y: &'a mut Container = x;
Run Code Online (Sandbox Code Playgroud)
但是当我这样做时,编译器会遇到问题:
test_3.rs:25:5: 25:10 error: cannot assign to `x` …Run Code Online (Sandbox Code Playgroud) 我有两个类型的变量&T,x并且y我在函数内部交换:
pub fn foo<T: Copy>(mut x: &T) {
let y_owned = *x;
let mut y = &y_owned;
for _ in 0..10 {
do_work(x, y);
std::mem::swap(&mut x, &mut y);
}
}
fn do_work<T>(_x: &T, _y: &T) {}
Run Code Online (Sandbox Code Playgroud)
此代码无法编译,给出以下错误:
error[E0597]: `y_owned` does not live long enough
--> src/lib.rs:3:22
|
3 | let mut y = &y_owned;
| ^^^^^^^ borrowed value does not live long enough
...
8 | }
| - borrowed value only lives until …Run Code Online (Sandbox Code Playgroud) 最小的例子是这样的(Playground):
#[derive(Debug)]
struct Node {
id: usize,
}
fn main() {
let mut node = Node { id: 0 };
let mut lastnode = &mut node;
let mut last = lastnode; // move
(*last).id = 1;
println!("{:?}", last);
//println!("{:?}", lastnode);
let mut node2 = Node { id: 2 };
lastnode = &mut node2;
last = lastnode; // doesn't move to "last"
println!("{:p}", last); // "last" and "lastnode" point to the same address
println!("{:p}", lastnode);
}
Run Code Online (Sandbox Code Playgroud)
为什么第一个会last = …
fn main() {
let mut v = vec![1, 2, 3];
go(&mut v);
// still need v here, so I can't pass ownership to the "go' method above
println!("{}", v.len())
}
fn go(v: &mut Vec<i32>) {
for i in v {
println!("{}", i);
}
v.push(4);
}
Run Code Online (Sandbox Code Playgroud)
我想在子函数中改变向量而不传递该向量的所有权。子函数需要迭代向量并对其进行变异。
然而,由于以下错误,上面的代码不起作用:
error[E0382]: borrow of moved value: `v`
--> src/main.rs:14:5
|
10 | fn go(v: &mut Vec<i32>) {
| - move occurs because `v` has type `&mut Vec<i32>`, which does not implement the `Copy` trait …Run Code Online (Sandbox Code Playgroud) 从借用规则来看:
下面,我有一个 Foo 结构(整个结构)的可变借用,这意味着我借用了该结构的每个字段。不过,我可以在功能上再借用一下它的领域demo。我怀疑我有两个可变引用x.a:
#[derive(Debug)]
struct Foo {
a: i32,
b: i32,
}
fn demo(foo: &mut Foo) {
// the `foo` is mutable borrow
// should have exclusive access to all elements of Foo instance
// However,
let bar = &mut foo.a; // second ref to `x.a`
*bar += 1;
let baz = &foo.b;
println!("{:?}", bar);
println!("{:?}", baz);
}
fn main() {
let mut x = Foo { a: 10, b: 1 };
let foo …Run Code Online (Sandbox Code Playgroud)