I'm having trouble with the lifetime of a buffer.
I want my main program to be responsible to fill a struct and a buffer. My struct fills the buffer in an "infinite" loop. For each iteration of the loop, I want to print the buffer content. Something like this:
fn main() {
let mut buffer = [0.0; 1024];
let mut obj = MyObject::new(&mut buffer);
loop {
obj.fill_buffer();
for i in 0..1024 {
println!("Sample {}: {}", i, buffer[i]);
}
}
}
My struct looks like this:
struct MyObject<'a> {
a_value: f64,
buffer: &'a mut [f64],
}
impl<'a> MyObject<'a> {
fn new(buffer: &'a mut [f64]) -> MyObject<'a> {
MyObject { a_value: 1.0, buffer: buffer }
}
fn fill_buffer(&mut self) {
for i in 0..self.buffer.len() {
self.buffer[i] = 1.0;
}
}
}
From the error messages "cannot borrow buffer
as immutable because it is also borrowed as mutable" and things like this which depends on my tests and rust documentation, I understand that the problem comes from that I display buffer just after the call fill_buffer
.
fill_buffer
uses a reference and it seems to pose a problem to rust to call it and to get value just after in the same scope.
How can I have an infinite loop that calls fill_buffer
on the struct and displays it just after? I want main
to be responsible for creating the buffer. And I want the buffer to be in the struct, not passed as parameter to fill_buffer
.
EDIT Here is the code corrected with accepted answer of kmdreko:
struct MyObject<'a> {
a_value: i64,
buffer: &'a mut [f64],
}
impl<'a> MyObject<'a> {
fn new(buffer: &'a mut [f64]) -> MyObject<'a> {
MyObject { a_value: 0, buffer: buffer }
}
fn fill_buffer(&mut self) -> &[f64] {
for i in 0..self.buffer.len() {
self.buffer[i] = i as f64 * self.a_value as f64;
}
self.buffer
}
}
fn main() {
let mut buffer = [0.0; 8];
let mut obj = MyObject::new(&mut buffer);
for i in 1..9 {
obj.a_value = i;
let buffer = obj.fill_buffer();
for j in 0..8 {
println!("Loop {}: subloop: {}: sample {}", i, j, buffer[j]);
}
}
}
You have given exclusive access of buffer
to obj
by holding a mutable reference, so main()
can't access buffer
while obj
has it.
I see two options:
re-create obj
on each iteration of the loop, so it may be destroyed (releasing its exclusive access) before printing at the end, or
borrow the buffer back:
impl<'a> MyObject<'a> {
fn buffer(&self) -> &[f64] {
self.buffer
}
}