gpt4 book ai didi

macros - 是否可以使用 Rust 宏以程序方式声明变量?

转载 作者:行者123 更新时间:2023-11-29 08:20:27 24 4
gpt4 key购买 nike

基本上,这个问题有两个部分:

  1. 你能在 Rust 中将未知标识符传递给宏吗? ?

  2. 你能在 Rust 宏中组合字符串来生成新的变量名吗?

例如,像这样的东西:

macro_rules! expand(
($x:ident) => (
let mut x_$x = 0;
)
)

调用 expand!(hi) 明显失败,因为 hi 是一个未知的标识符;但你能以某种方式做到这一点吗?

即。 C 中的等价物如下:

#include <stdio.h>
#define FN(Name, base) \
int x1_##Name = 0 + base; \
int x2_##Name = 2 + base; \
int x3_##Name = 4 + base; \
int x4_##Name = 8 + base; \
int x5_##Name = 16 + base;

int main() {
FN(hello, 10)
printf("%d %d %d %d %d\n", x1_hello, x2_hello, x3_hello, x4_hello, x5_hello);
return 0;
}

你为什么这么说,多么糟糕的想法。为什么你会想要那样做?

很高兴你提出这个问题!

考虑这个 rust block :

{
let marker = 0;
let borrowed = borrow_with_block_lifetime(data, &marker);
unsafe {
perform_ffi_call(borrowed);
}
}

你现在有一个没有使用结构生命周期的明确限定生命周期(标记)的借用值,但我们可以保证在 ffi 调用的整个范围内存在;同时,我们不会遇到模糊的错误,其中 * 在不安全的 block 中被不安全地取消引用,因此编译器不会将其捕获为错误,尽管发生了错误 < em>在安全区内。

(另见 Why are all my pointers pointing to the same place with to_c_str() in rust?)

使用可以为此目的声明临时变量的宏将大大减轻我与编译器打交道的麻烦。这就是我想要这样做的原因。

最佳答案

是的,但是这仅作为夜间实验性 API 提供,可能会被删除。

您可以将任意标识符传递给宏,是的,您可以使用 concat_idents!() 将标识符连接成一个新的标识符。宏观:

#![feature(concat_idents)]

macro_rules! test {
($x:ident) => ({
let z = concat_idents!(hello_, $x);
z();
})
}

fn hello_world() { }

fn main() {
test!(world);
}

但是,据我所知,因为 concat_idents!() 本身是一个宏,所以您不能在任何地方使用这个串联标识符,您可以使用普通标识符,仅在某些地方,如上面的示例,在我看来,这是一个巨大的缺点。就在昨天,我试图编写一个可以删除代码中大量样板的宏,但最终我无法做到,因为宏不支持任意放置串联标识符。

顺便说一句,如果我没有正确理解您的想法,您实际上并不需要连接标识符来获得唯一的名称。 Rust 宏,与 C 宏相反,是 hygienic .这意味着在宏内部引入的所有局部变量名称都不会泄漏到调用该宏的范围内。例如,您可以假设此代码有效:

macro_rules! test {
($body:expr) => ({ let x = 10; $body })
}

fn main() {
let y = test!(x + 10);
println!("{}", y);
}

也就是说,我们创建了一个变量x,并在它的声明之后放置了一个表达式。然后很自然地认为 test!(x + 10) 中的 x 指的是宏声明的那个变量,一切都应该没问题,但实际上这段代码不会编译:

main3.rs:8:19: 8:20 error: unresolved name `x`.
main3.rs:8 let y = test!(x + 10);
^
main3.rs:3:1: 5:2 note: in expansion of test!
main3.rs:8:13: 8:27 note: expansion site
error: aborting due to previous error

因此,如果您只需要局部变量的唯一性,那么您可以安全地什么也不做,使用您想要的任何名称,它们将自动是唯一的。这是 explained在宏教程中,尽管我发现其中的示例有些令人困惑。

关于macros - 是否可以使用 Rust 宏以程序方式声明变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52350857/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com