A "while loop" and ownership of input paramers passed?

Hello everyone,

I am new to Rust and this is a beginner question about ownership and passing parameters inside a loop to a function.

I have a while loop that calls a function.
Function requires a struct as input, not a reference to struct, but the actual struct.
I did not write the library so I can not change the function interface to use a &reference.
The function is part of the library I am using - AWS SDK rusoto.

I want to call the function inside a loop such as while loop.

pseudo-code:

while (condition) {
var = function( mystruct );
}

Rust compiler complains about mystruct ownership since its called inside the loop so it is "swallowed up" by the function call, if I understand ownership correctly.

Question: what is the recommended way of dealing with this pattern, given the function does not request a &reference to a struct but the actual struct object as a parameter.

I worked around this issue by creating a new instance of mystruct just before the call so if the function is called 10,000 times then the mystruct object will be created (and destroyed) 10,000 times. This seems like a performance hit plus more code required as I have to create new struct inside the loop.

Here is work-around pseudo-code:

while (condition) {
mystruct = new();
var = function( mystruct );
}

Is this the recommended way ?
Is there a Rust idiomatic way of dealing with the parameters passed to functions inside a loop ?

many thanks

If your function requires ownership of the object, you will have to create a new one for every call. If you can, try changing the function take a reference instead of a value, which would not take ownership of it.

1 Like

It very much depends on your case. Probably the best way is to define function in way so it borrows argument instead of taking ownership, but if it requires copying whole argument, then its better to do it outside of function call - for eg function(mystruct.clone()).

2 Likes

Hi, if your type is small enough and bitwise copiable you can derive Copy. If it isn't there is Clone (as @hashedone already showed) but it's equivalent to what you are already doing.
We could probably help you more if you gave us the definition of the struct and/or the name of the function.

1 Like

thank you everyone who replied.

The rusoto crate structure I am passing is this:

#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct GetQueryExecutionInput {
/// The unique ID of the query execution
#[serde(rename = "QueryExecutionId")]
pub query_execution_id: String,
}

So it is just one String, which I ended up cloning for each call to the function below.

The function: (as you can see there is no &Reference argument).

fn get_query_execution( &self, input: GetQueryExecutionInput) -> RusotoFuture<GetQueryExecutionOutput, GetQueryExecutionError>

Returns information about a single execution of a query if you have access to the workgroup in which the query ran. Each time a query executes, information about the query execution is saved with a unique ID

Therefore, I have done it correctly, I cloned the object before each call to the function inside the while loop.
As I understand Rust ownership, this struct parameter which I clone on each call will get automatically released/freed when the called function returns. In other words, if I call this function 1 million times in the loop there will be no memory leaking from all those objects I cloned and passed into the function.
Is that correct?

thank you for your support!

Yes Clone is the way to go.

The function you call can itself call other functions and give them ownership. It can also free it instantly, so you don't know (without looking at the source) when it will get dropped but it will. The latest being the end of the function. On your end, you've done the job, it's not your responsibility anymore.
Just to be thorough nothing prevents the function from leaking the String, it wouldn't even be unsafe but it's very unlikely.

While taking a quick look at the doc I stumbled upon batch_get_query_execution maybe it's something you might be interested in?

1 Like

many thanks again! This is most useful to confirm my understanding.

There is also an open issue to do something about it.