Hi all!
I know this specific error has been asked thoroughly (I apologize for the repetition!), but I still can't understand while this error raises an error.
use num_bigint::{BigInt, ToBigInt};
use std::{cmp::Ordering, ops::Add};
impl Add for Decimal {
type Output = Decimal;
fn add(self, rhs: Self) -> Self::Output {
let lmsd = self.mantissa.to_str_radix(10).chars().nth(0).unwrap().to_digit(10).unwrap(); //should be ok since decimal numbers are ASCII
let rmsd = rhs.mantissa.to_str_radix(10).chars().nth(0).unwrap().to_digit(10).unwrap();
let mut res_mantissa = self.mantissa + rhs.mantissa;
let mut res_integral = self.integral + rhs.integral;
let res_msd = res_mantissa.to_str_radix(10).chars().nth(0).unwrap().to_digit(10).unwrap();
if res_msd < lmsd || res_msd < rmsd { // overflow
res_integral += 1;
let res_str = res_mantissa.to_str_radix(10).chars().as_str();
res_mantissa = res_str[1..res_str.len()].parse::<BigInt>().unwrap();
}
Decimal{ integral: res_integral, mantissa: res_mantissa }
}
}
It comes from an Exercism's exercise. cargo check
returns
cargo check --benches --tests --all-features
Checking decimal v0.1.0 (/home/alessandro/exercism/rust/decimal)
error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:29:20
|
29 | let res_str = res_mantissa.to_str_radix(10).chars().as_str();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary which is freed while still in use
30 | res_mantissa = res_str[1..res_str.len()].parse::<BigInt>().unwrap();
| ------- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
IIUC, to_str_radix()
gives a String
, which is created but not bound to a variable, since in res_str
I actually save chars().as_str()
. However, this retruns a &str
, a reference to a memory area containing a String
. So first question is: why is the value dropped, even if I could still access that memory (I'm even in the same block)? My guess is that the String
object is allocated on the heap, but since it is not saved anywhere it is immediately deallocated. However, having a reference to it, that shouldn't be dropped, should it?
Then, trying to fix it, I found that adding at the end of line 29 to_owned()
solves the problem (since it creates a copy of the String
, and in fact now the type of res_str
is not &str
, but String
). However, clone()
doesn't work. Why? Is it because it copies the reference, and not the string (I see the type in that case remains &str
)?
Can you please tell me if I understood everything correctly, or if I got something wrong?
Thanks!