'How to return the value of a reference field of a struct that is no longer used without copy?

Code like this:

pub fn sample_from_categorical_logits(prob_logits: Tensor) -> (Tensor, Tensor) {
    let prob_obj = match prob_logits.size().len() {
        3 => Categorical::from_logits(prob_logits),
        2 => Categorical::from_logits(prob_logits.unsqueeze(1)),
        _ => panic!("illegal..."),
    };
    (prob_obj.sample(&[]), (*prob_obj.probs()).copy())//TODO: can copy be avoided?
}

I can get an immutable reference on a field of object prob_obj through prob_obj.prob(). Now I need to return the value of it, because I need to read(only) this value for some calculation, and return this value and calculated value further.

Tensor is a 3rd struct doesn't implement Copy trait.

I know I can't return a reference of a local object. But in this case, since I no longer need the whole prob_obj object, I wonder if there is a more efficient way other than copying the field, like move in C++.

I googled, found something like Cow, Mem::take, and UnSafe, but they seem to be not the use case here.



Solution 1:[1]

I wonder if there is a more efficient way other than copying the field, like move in C++.

Well yes, moving. But moving requires having ownership of the object, meaning you need a version of probs() which consumes the object in order to return its bits.

Or one which returns a mutable reference in order to use mem::take or mem::swap.

Like you would in C++, really, it's not like you can just move stuff out of a const reference (at best that's going to perform a copy).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Masklinn