【发布时间】:2022-01-28 13:18:26
【问题描述】:
我开始学习 Rust,我承认,我在生命周期和借用方面存在一些问题。在偶数天我认为我得到了它,在奇数天我被咬了! C 或 C++ 太多?或者也许太老了? ;-)
以下代码无法编译:
use core::f64::consts::PI;
pub struct TableOscillator {
sample_rate: u32,
table: &[f64],
}
impl TableOscillator {
pub fn new(sample_rate: u32, table: &[f64]) -> TableOscillator {
TableOscillator { sample_rate, table }
}
// Other methods ...
}
fn main() {
const SAMPLE_RATE: u32 = 96000;
let table: [f64; 1024];
for i in 0..table.len() {
let phase = (2.0 * PI * i as f64) / (table.len() as f64);
table[i] = phase.sin();
}
// At this point I would like "table" to be constant and usable by all the following oscillators.
let osc1 = TableOscillator::new(SAMPLE_RATE, &table);
let osc2 = TableOscillator::new(SAMPLE_RATE, &table);
// ...
}
这是编译器消息:
error[E0106]: missing lifetime specifier
--> src/main.rs:5:12
|
5 | table: &[f64],
| ^ expected named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
3 ~ pub struct TableOscillator<'a> {
4 | sample_rate: u32,
5 ~ table: &'a [f64],
|
一点解释:不同的振荡器使用它们的“表”成员(只读不写)。 解决这个问题的 Rust 惯用方法是什么? 谢谢!
【问题讨论】:
-
如果你按照编译器告诉你的去做会发生什么?
-
学习如何应用生命周期绝对值得,但如果你的目标是首先让一些简单的 Rust 工作,那么如果你存储一个拥有的
Vec<f64>而不是借来的切片,这个项目会非常简单。除非您计划拥有至少数百个振荡器,否则复制额外 8kB 的成本可能不值得管理生命周期的麻烦(如果确实如此,请考虑使用Cow而不是存储切片)。来自编译器团队成员之一的一些好建议:twitter.com/ekuber/status/1476128384908410882 如果您接受一些复制,Rust 会简单得多。 -
@Caesar:是的,它有帮助。感谢您的链接!
-
@Jmb:你是对的,但是当我按照编译器告诉我的操作时,我打错了!
-
@RobNapier:感谢您的解释。我将使用大量具有更大样本表的振荡器。也感谢有趣的链接。