The closure in the following code creates an instance of Series
. This prevented me from creating a reference and storing it in the iters: Vec<_>
. I was getting the "reference to temporary value" error.
To extend the lifetime of the value, I created a local_global_series: Vec<Series>
outside of the closure. I was pretty confident that this solution would do the trick. But the compiler came back with:
captured variable cannot escape `FnMut` closure body
`FnMut` closures only have access to their captured variables while they are executing...
...therefore, they cannot allow references to capture variables to escape
pub fn build_logit(mut self) -> Result<Matrix<LogitData>> {
let iters: DataFrame = self.select(predictors)?;
let mut local_global_series: Vec<Series> = Vec::with_capacity(rows);
let mut iters = iters // issue is not caused by mutability here
.iter()
.map(|s| { // <<< inferred FnMut closure
local_global_series.push( // <<< variable captured here
s.cast(&DataType::Float64)
.expect("Tried to cast to Float64 failed"),
);
let r = local_global_series.last().unwrap();
let result = r.f64()?.into_iter(); // uses ref to local_global,
// returns something that borrows/relies
// on the value
Ok(result) // <<< cannot escape error here
})
.collect::<Result<Vec<_>>>()?;
larger context
impl Matrix<DataFrame> {
fn new(inner: DataFrame) -> Self {
Matrix { inner }
}
pub fn build_logit(mut self) -> Result<Matrix<LogitData>> {
self.reshape_to_logit()?;
let iters: DataFrame = self.select(predictors)?;
let mut local_global_series: Vec<Series> = Vec::with_capacity(rows);
let mut iters = iters
.iter()
.map(|s| { // <<< inferred FnMut closure
local_global_series.push( // <<< variable captured here
s.cast(&DataType::Float64)
.expect("Tried to cast to Float64 failed"),
);
let r = local_global_series.last().unwrap();
let result = r.f64()?.into_iter(); // uses ref to local_global,
// returns something that borrows/relies
// on the value
Ok(result) // <<< cannot escape error here
})
.collect::<Result<Vec<_>>>()?;
for _ in 0..self.height() {
for iter in &mut iters {
let value = iter.next().expect("should have as many iterations as rows");
data.push(value.unwrap() as f64);
}
}
// true means row major layout of array
let logit_matrix = Matrix::<LogitData>::new(DenseMatrix::new(rows, cols, data, true), y);
Ok(logit_matrix)
}
}
Q1
Just to level-set, it would be great to hear again how/if its possible to invalidate the references to a mutable object
Q2
Is there another workaround to this problem?