我正在关注正弦例子 https://github.com/RustAudio/rust-portaudio/blob/master/examples/sine.rs在 rust-portaudio 示例目录(使用非阻塞 API)中,我试图获取run()
使用 Trait 类型参数而不是计算其中的样本run()
itself.
我定义的特征非常简单:
pub trait Evaluatable {
fn evaluate(&mut self) -> (f32, f32);
}
我改变了run()
函数签名如下以接受我的特征:
fn run<E: Evaluatable + 'static>(mut generator: E) -> Result<(), pa::Error>
并更新了回调函数来调用evaluate()
在特征类型上而不是生成样本本身:
let callback = move |pa::OutputStreamCallbackArgs { buffer, frames, .. }| {
let mut idx = 0;
for _ in 0..frames {
let samples = generator.evaluate();
buffer[idx] = samples.0;
buffer[idx+1] = samples.1;
idx += 2;
}
pa::Continue
};
E
必须'static
由于此回调(请参阅open_non_blocking_stream() https://github.com/RustAudio/rust-portaudio/blob/master/src/lib.rs#L472),这是我沮丧的主要原因......
In main
,我可以创建一个Evaluatable
输入并传递它就好了(旁白:我很惊讶这能起作用,在中做对象main
get 'static
寿命?):
fn main() {
// Implements Evaluatable
// arguments are: sample rate, frequency, amplitude
let mut sine_generator = SineGenerator::new(44100.0, 200.0, 0.3);
run(sine_generator).unwrap()
}
但我希望能够组合信号,所以我制作了一个可以组合它们的结构:
use evaluatable::Evaluatable;
pub struct Combine<'a> {
first: &'a mut (Evaluatable + 'a),
second: &'a mut (Evaluatable + 'a),
}
impl<'a> Combine<'a> {
pub fn new(first: &'a mut Evaluatable, second: &'a mut Evaluatable) -> Combine<'a> {
Combine {first, second}
}
}
impl<'a> Evaluatable for Combine<'a> {
fn evaluate(&mut self) -> (f32, f32) {
let first_output = self.first.evaluate();
let second_output = self.second.evaluate();
(first_output.0 + second_output.0, first_output.1 + second_output.1)
}
}
并尝试将其用于main()
:
fn main() {
let mut sine_generator1 = SineGenerator::new(44100.0, 200.0, 0.3);
let mut sine_generator2 = SineGenerator::new(44100.0, 250.0, 0.3);
let combine = Combine::new(&mut sine_generator1, &mut sine_generator2);
run(combine).unwrap()
}
现在,Rust 似乎有一个问题,即生命周期不存在'static
:
Error[E0597]: `sine_generator1` does not live long enough
--> src/main.rs:27:37
|
27 | let combine = Combine::new(&mut sine_generator1, &mut sine_generator2);
| ^^^^^^^^^^^^^^^ does not live long enough
28 | run(combine).unwrap()
29 | }
| - borrowed value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
- 为什么 Rust 能够让我使用
SineGenerator
from main()
,但不让我使用Combine
它采用相同的对象(我认为具有相同的生命周期)?
- 有没有更好的实现方法
Combine
这能让我在这里做我想做的事吗?我必须引用,因为 Trait 类型在编译时没有定义大小。