我最近在一个项目中编写了很多宏.我只想到Rust的模块系统对管理"名称空间"有多么有用,我开始怀疑:
为什么决定宏不应该遵守模块系统?是因为宏观使用普遍罕见吗?还是因为其他一些基本的编译过程限制了它?
是否可以"命名"Rust宏?
这个问题不是出于迫切的需要,而是来自一般的好奇心:-)
我正在努力从我的生锈库中制作宏以供其他生锈项目使用.
这是我现在如何尝试这项工作的一个例子.
lib.rs:
#![crate_name = "dsp"]
#![feature(macro_rules, phase)]
#![phase(syntax)]
pub mod macros;
Run Code Online (Sandbox Code Playgroud)
macros.rs:
#![macro_escape]
#[macro_export]
macro_rules! macro(...)
Run Code Online (Sandbox Code Playgroud)
other_project.rs:
#![feature(phase, macro_rules)]
#![phase(syntax, plugin, link)] extern crate dsp;
macro!(...) // error: macro undefined: 'macro!'
Run Code Online (Sandbox Code Playgroud)
我是在正确的轨道上吗?我一直在尝试使用std :: macros作为参考,但我似乎没有太多运气.我有什么明显的遗失吗?
我希望能够得到以下内容:
macro_rules! impl_a_method(
($obj:ident, $body:block) => (
fn a_method(foo: Foo, bar: Bar, baz: Baz) -> $obj $body
)
)
// Implementation would look like:
impl_a_method!(MyType, {
MyType {
foo: foo.blah(),
bar: bar.bloo(),
baz: baz.floozy(),
}
})
Run Code Online (Sandbox Code Playgroud)
我的真实世界示例包含具有更大签名的方法,我必须以30多种不同类型的独特方式实现这些方法.
我曾尝试与上述类似的宏观的东西,但是我碰到哪里rustc认为的错误foo,bar并且baz在扩展网站未解决的名称(即使我敢肯定,宏声明词汇之前使用).
可以这样做吗?
如果没有,你能推荐一种能达到类似效果的方法吗?
我目前正在用 C++ 使用 openFrameworks 编写一个程序音乐引擎。我可以生成一首歌曲并从规范化(-1 和 1 之间)的浮点数缓冲区中播放它,效果非常好,但是当我尝试将相同的浮点数缓冲区写入 32 位 .WAV 时,我遇到了一些问题文件。
当我在 Finder 的预览中播放该文件时(我使用的是 OSX 10.9.2),整个歌曲持续时间的播放都被严重削波和扭曲。它似乎能够很好地读取格式,因为它显示了正确的文件持续时间、比特率和采样率https://i.stack.imgur.com/fz2w8.png。奇怪的是,当我将同一个文件拖到 Logic Pro X 中时,它可以正常读取、成功转换并且播放时没有失真。它还生成一个波形显示,我可以在其中看到两个通道的波形(文件是立体声)完全标准化(至少对于前半部分......请参阅下一期)。
虽然 Logic Pro X 能够比 Finder 的预览更成功地读取文件,但在歌曲的中间位置会出现大幅振幅跳跃,并且波形开始削波(尽管远不及 Finder 播放中的削波幅度)。我尝试写入 .WAV 的每首生成的歌曲都会发生这种情况(它们每次在结构、节奏和乐器上都不同)。您可以在此处查看示例https://i.stack.imgur.com/59y5w.jpg。
以下是我用来写入 .WAV 文件的代码:
template <typename T>
void write(std::ofstream& stream, const T& t) {
stream.write((const char*)&t, sizeof(T));
}
template <typename SampleType>
void writeWAVData(const char* outFile, SampleType* buf, size_t bufSize, int sampleRate, short channels)
{
std::ofstream stream(outFile, std::ios::binary); // Open file stream at "outFile" location
/* …Run Code Online (Sandbox Code Playgroud) 我的目标是检索矩阵中所有元素的迭代器以及与每个元素关联的行号.
以下是我遇到的生命周期问题的简化版本.
fn main() {
let mat = [ [1i32, 2, 3],
[4, 5, 6],
[7, 8, 9] ];
// Create an iterator that produces each element alongside its row number.
let all_elems = mat.iter().enumerate().flat_map(|(row, arr)| {
arr.iter().map(|elem| (row, elem)) // Error occurs here.
});
for (row, elem) in all_elems {
println!("Row: {}, Elem: {}", row, elem);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我得到的错误:
<anon>:10:9: 10:43 error: cannot infer an appropriate lifetime for lifetime parameter 'r in function call due to conflicting requirements
<anon>:10 …Run Code Online (Sandbox Code Playgroud) 在花了相当长的时间浏览了广泛的 Core Audio 文档迷宫之后,我仍然不确定应该使用 C API 的哪一部分来在 OS X 中创建基本的音频示例 I/O 流。
当我说“I/O 流”时,我指的是为特定音频设备生成的低延迟流(具有采样率、通道数、位深度等参数)并接收/请求交错音频样本的缓冲区由设备播放。
如果有人能指出我需要实现此目标的标头和相关函数(甚至可能是一个示例),我将非常感激:)谢谢!
PS:通常我会使用 PortAudio 来实现这一点,但在这种情况下,我有兴趣直接访问 Core Audio 框架,以帮助朋友创建一个纯粹的 Rust 便携式音频平台。另外,我已将这个问题发布到苹果开发者论坛,但尚未收到回复,所以我想我应该在这里尝试。如果有更合适的交流/论坛可以询问,请告诉我。
这个问题是相关的,但是它更涵盖了为什么编译器在从 返回可变引用时无法推断安全生命周期的原因Iterator::next,我想我理解。
我的问题是:
在设计自己的迭代器以生成可变引用时,您可以采取哪些具体步骤?最终,我希望有一个尽可能简洁、分步、注释的示例,说明 aIterator及其next实现,当他们遇到这种情况时,我(和任何人)可以将其作为明确的参考。unsafe例子很好,我想它们可能是必要的!
注意:我知道这MutItems通常是推荐的示例,但是它的实现可能很难遵循,因为没有关于 1. 标记在那种情况下如何工作以及 2.iterator!宏扩展到什么以及它如何工作的任何文档。如果你用MutItems你的例子,你能澄清这些事情吗?