V
V
Vasily Melnikov2019-02-11 10:36:30
Rust
Vasily Melnikov, 2019-02-11 10:36:30

How to pass references to two elements of a vector to a function?

Rust just started groping. And naturally all sorts of misunderstandings with the behavior of "borrowed content".
Here, for example, there is a vector of structures, and I want to do something with the contents of several elements of this vector.
I pass mutable references to the function. And I get:

131 |     foo(&mut v[0], &mut v[1]);
    |     ---      -          ^ second mutable borrow occurs here
    |     |        |
    |     |        first mutable borrow occurs here
    |     first borrow later used by call

As a test, I tried calling on a couple of regular variables on the stack. Everything works as expected.
There is a double-copy workaround that looks wild.
By the way, why doesn't it compile? Cloning is required. The actual code, there are all three options at once ...
let mut va : P = v[0];
#[derive(Debug, Clone)]
struct P {
  x : i32,
  y : i32
}

fn foo(a : &mut P, b : &mut P) 
{
  a.x = b.x + 1;
  b.y = a.y + 1;
}

fn main() 
{
// Это ожидаемо работает
  let mut a = P{x:1, y:2};
  let mut b = P{x:10, y:20};
  
  foo(&mut a, &mut b);

  println!("{:?} {:?}", a, b);

  let mut v : Vec<P> = [
      P{x:1, y:2}, 
      P{x:10, y:20}
    ].to_vec();

// А это уже нет !!!
//	foo(&mut v[0], &mut v[1]);   


// Так можно "обойти",  но это явно не то ради чего придумывался rust
  let mut va : P = v[0].clone();
  let mut vb : P = v[1].clone();

  foo(&mut va, &mut vb);

  v[0] = va;
  v[1] = vb;

  println!("{:?}", v);
}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Andrey Lesnikov, 2019-02-11
@BacCM

https://stackoverflow.com/questions/30073684/how-t...
TLDR: you want https://doc.rust-lang.org/std/primitive.slice.html... because Rust only allows you to have one active changing reference to the entity, and the knowledge of how the slice/vector works is not hardwired into the language, i.e. this is solved by functions with unsafe inside.

I
inv2004, 2019-02-22
@inv2004

It is in the code as you wrote, and as you pass it to the function, that it looks more like a tuple:
in this case, everything would work.
If it's still a vector, then Rust needs to know how the vector works to ensure that there are no problems with a double mutable reference.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question