我在理解Rust 的范围时遇到了问题.我try 实现一个简单的代码来播放声音.我想填充缓冲区然后播放它,但我无法让它编译.
我得到了这个方法:
fn main() {
let channels: usize = 2;
let device = initialize_device();
let config = initialize_configuration(&device, channels as u16);
let mut stream_buffer = [0.0 as f32; 64];
{
let mut oscillator = Oscillator::new(440.0 as f32, 0.0 as f32, 44100.0 as f32, &mut stream_buffer);
let processor = move |_data: &mut [f32], _: &cpal::OutputCallbackInfo| {
//FIXME: Send data from oscillator to _data
oscillator.process();
};
let stream = build_outputstream(config, device, Box::new(processor));
let _ = stream.play();
std::thread::sleep(std::time::Duration::from_millis(2000));
}
}
变量"stream_buffer"位于作用域之前
let mut stream_buffer = [0.0 as f32; 64];
{
...
}
在那里执行其余代码.
根据我从rust文档中了解到的情况,默认情况下,变量位于堆栈上,我们可以将它们装箱以将它们放在堆上.
因此,stream_buffer
位于堆栈上,并且应该保留在堆栈上直到程序结束.即使我没有手动创建它下面的范围.
该文档还表示,堆上的变量在超出范围时会自动销毁.
所以,我知道我的盒装processor
的生命周期比stream_buffer
短,并且它在其范围结束时被销毁.
let mut stream_buffer = [0.0 as f32; 64];
{
let mut oscillator = Oscillator::new(440.0 as f32, 0.0 as f32, 44100.0 as f32, &mut stream_buffer);
let processor = move |_data: &mut [f32], _: &cpal::OutputCallbackInfo| {
//FIXME: Send data from oscillator to _data
oscillator.process();
};
let stream = build_outputstream(config, device, Box::new(processor));
...
}
但编译器抱怨"stream_buffer"不够活跃.
error[E0597]: `stream_buffer` does not live long enough
--> src\main.rs:42:88
|
40 | let mut stream_buffer = [0.0 as f32; 64];
| ----------------- binding `stream_buffer` declared here
41 | {
42 | let mut oscillator = Oscillator::new(440.0 as f32, 0.0 as f32, 44100.0 as f32, &mut stream_buffer);
| ^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
...
49 | let stream = build_outputstream(config, device, Box::new(processor));
| ------------------- cast requires that `stream_buffer` is borrowed for `'static`
...
55 | }
| - `stream_buffer` dropped here while still borrowed
|
= note: due to object lifetime defaults, `Box<dyn for<'a, 'b> FnMut(&'a mut [f32], &'b OutputCallbackInfo) + Send>` actually means `Box<(dyn for<'a, 'b> FnMut(&'a mut [f32], &'b OutputCallbackInfo) + Send + 'static)>`
如果我按照编译器建议的那样将stream_buffer
设置为静态,它就会起作用.但我不想.
我想我明白,因为处理器必须在堆上,所以我别无 Select ,只能让stream_buffer
保持静态?我不能把stream_buffer
放在堆栈上,把处理器放在堆上吗?