3
eeee
5y

Rust noob Q:

Given x a variable on the heap, e.g.

let x = String::from("Hello, devRant!");

Then, given some function that I didn't write (from a library) that takes ownership of its argument:

fn some_function(y: String) -> bool { ... }

How would you handle this situation:

if some_function(x) {
another_function(x); // not ok, because x has gone out of scope in the line before
}

Is it idiomatic to just clone() x in the first call? That seems bad practice, because it's the second (or some other additional) call that needs x. What should I be doing instead?

Comments
  • 1
    let x = String::from("whatever");

    if some_function(x.clone()) {
    another_function(x.clone());
    ...
    last_use_of_x(x);
    }

    Use the clone method.

    Edit: Depending on the implementation, you could pass a reference to x. That would look like this: some_func(&x);
  • 1
    @highlight
    let x = String::from("whatever");

    if some_function(x.clone()) {
    another_function(x.clone());
    // ... 
    last_use_of_x(x);
  • 1
  • 1
    @olback @highlight how is that idiomatic? What if I remove the last use of x, then the previous clone() is unnecessary and that seems like a code smell to me, isn't it?
  • 0
  • 0
    @eeee I'm just a rust beginner myself and this is the only solution I know of.

    I use the clone method and, well, it works. I'm not aware of any better alternative.

    I've never looked at "professional rust code". Maybe the use of clone is common, I don't know. 🤷‍♂️
  • 1
    I think it really depends what are those functions doing. Mostly you don't need to transfer ownership so you can use references. Use references as much as you can.

    Variables cloning is a relatively slow process (especially if they are stored in heap, like String - with capital S, or vector) and it takes memory. Don't make your data redundant, if you don't have to.
  • 1
    Well first, that library seems to be poorly written. If it's a basic check, then it should not take ownership over 'x',it should work on a ref to x.

    You can try and get around it by doing

    let test = some_function(x);
    if(test) {
    do_more_with(x)
    }
Add Comment