Error: using relocated res value in Rust

What's with this code:

fn method1(a: &str) -> (String, String) {
  let res = method2(a);
  (res.val0(), res.val1())
}

      

Mistake:

error: use of moved value res

      

How to fix it?

+3


source to share


1 answer


It looks like it method2()

returns a non-copyable object, whereas the methods val0()

and val1()

take a target by value:

struct SomeType { ... }

impl SomeType {
    fn val0(self) -> String { ... }
    fn val1(self) -> String { ... }
}

fn method2(a: &str) -> SomeType { ... }

fn method1(a: &str) -> (String, String) {
    let res = method2(a);
    (res.val0(), res.val1())
}

      

Since SomeType

it cannot be copied automatically, it will be moved to methods that take it by value, but you try to do it twice, which is unreasonable, and the compiler reports a "use of the moved value" error.

If you cannot change SomeType

and it only has methods val0()

and val1()

, has no public fields and does not implement Clone

. then you're out of luck. You can only get the result of the method, val0()

or val1()

not both.

If it SomeType

also has methods that return references, for example:

impl SomeType {
    fn ref0(&self) -> &String { ... }
    fn ref1(&self) -> &String { ... }
}

      

( &str

instead of &String

fine too) then you can clone the lines:

let res = method2(a);
(res.ref0().clone(), res.ref1().clone())

      

It's even better if it SomeType

provides some kind of destructuring, like:



impl SomeType {
    fn into_tuple(self) -> (String, String) { ... }
}

      

Then it's simple:

method2(a).into_tuple()

      

If SomeType

is a two-element tuple, you don't even need to into_tuple()

, just write the method2()

call as is:

method2(a)

      

Tuples also provide tuple indexing syntax for tuples and tuples, rather than quickly aging tuples . It can also be used:

let res = method2(a);
(res.0, res.1)

      

It is redundant if SomeType

it is indeed a tuple of the same size, but if it SomeType

is a larger tuple, this is the way to go. Or you can use destructuring:

let (v1, v2, _) = method2(a);  // need as many placeholders as there are remaining elements in the tuple
(v1, v2)

      

+8


source







All Articles