我在同一个包中的两个模块中有两个模块,其中包已macro_rules
启用.我想在另一个模块中使用一个模块中定义的宏.
// macros.rs
#[macro_export] // or not? is ineffectual for this, afaik
macro_rules! my_macro(...)
// something.rs
use macros;
// use macros::my_macro; <-- unresolved import (for obvious reasons)
my_macro!() // <-- how?
Run Code Online (Sandbox Code Playgroud)
我目前遇到编译器错误" macro undefined: 'my_macro'
"...这是有道理的; 宏系统在模块系统之前运行.我该如何解决这个问题?
我正在尝试在 Rust 中编写我自己的派生模式宏,并且它的文档在示例中有些缺乏。
我有一个像这样的结构:
#[derive(MyMacroHere)]
struct Example {
id: i64,
value: Option<String>,
}
Run Code Online (Sandbox Code Playgroud)
我希望我的宏生成一个方法 à la
fn set_fields(&mut self, id: i64, value: Option<String>) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
使用TokenStream
特征来实现类似目标的基本步骤是什么?
我有一个自定义结构,如下所示:
struct MyStruct {
first_field: i32,
second_field: String,
third_field: u16,
}
Run Code Online (Sandbox Code Playgroud)
是否有可能以编程方式获取结构字段的数量(例如,通过方法调用field_count()
):
let my_struct = MyStruct::new(10, "second_field", 4);
let field_count = my_struct.field_count(); // Expecting to get 3
Run Code Online (Sandbox Code Playgroud)
对于这个结构:
struct MyStruct2 {
first_field: i32,
}
Run Code Online (Sandbox Code Playgroud)
......以下电话应该返回1
:
let my_struct_2 = MyStruct2::new(7);
let field_count = my_struct2.field_count(); // Expecting to get count 1
Run Code Online (Sandbox Code Playgroud)
有没有像这样的API field_count()
或者只能通过宏获得它?
如果使用宏可以实现这一点,那么应该如何实现?
我正在读一本关于Rust的书,并开始玩Rust宏.所有元变量类型都在那里解释并有示例,除了最后一个 - tt
.根据这本书,它是一个"单一的标记树".我很好奇,它是什么,它用于什么?你能举个例子吗?
我想创建一个指定次数打印"Hello"的宏.它的使用方式如下:
many_greetings!(3); // expands to three `println!("Hello");` statements
Run Code Online (Sandbox Code Playgroud)
创建该宏的天真方式是:
macro_rules! many_greetings {
($times:expr) => {{
println!("Hello");
many_greetings!($times - 1);
}};
(0) => ();
}
Run Code Online (Sandbox Code Playgroud)
但是,这不起作用,因为编译器不计算表达式; $times - 1
不计算,但作为一个新的表达式输入宏.
我一直#[tokio::main]
在我的一个程序中使用该宏。不合格的导入使用后main
,遇到了意想不到的错误。
use tokio::main;
#[main]
async fn main() {}
Run Code Online (Sandbox Code Playgroud)
error[E0659]: `main` is ambiguous
--> src/main.rs:3:3
|
3 | #[main]
| ^^^^ ambiguous name
|
= note: ambiguous because of a name conflict with a builtin attribute
= note: `main` could refer to a built-in attribute
Run Code Online (Sandbox Code Playgroud)
我一直在搜索文档,但找不到#[main]
任何地方描述的这个内置属性。Rust 参考包含内置属性的索引。该索引不包含#[main]
,但它包含名为 的属性#[no_main]
。
我对存储库进行了搜索rustlang/rust
,发现了一些似乎相关的代码,但它似乎使用了一对名为#[start]
和 的宏#[rustc_main]
,而没有提及其#[main]
本身。(这两个宏似乎都不能在稳定版上使用,会#[start]
发出一个错误,表明它不稳定,并#[rustc_main]
发出一个错误,表明它仅供编译器内部使用。)
我从名称中猜测它是为了将不同的函数标记为入口点而不是main
,但它似乎也没有这样做:
error[E0659]: …
Run Code Online (Sandbox Code Playgroud) 所以我有以下宏代码我正在尝试调试.我是从Rust Book的"The Deep end"一节中读到的.我重命名宏中的变量,以更密切地关注这篇文章.
我的目标是让程序打印出BCT程序的每一行.我很清楚这是编译器很重.
rustc给我的唯一错误是:
user@debian:~/rust/macros$ rustc --pretty expanded src/main.rs -Z unstable-options > src/main.precomp.rs
src/main.rs:151:34: 151:35 error: no rules expected the token `0`
src/main.rs:151 bct!(0, 1, 1, 1, 0, 0, 0; 1, 0);
Run Code Online (Sandbox Code Playgroud)
我可以采取什么步骤,以找出其中的宏观问题是从哪里来的?
这是我的代码:
fn main() {
{
// "Bitwise Cyclic Tag" automation through macros
macro_rules! bct {
// cmd 0: 0 ... => ...
(0, $($program:tt),* ; $_head:tt)
=> (bct_p!($($program),*, 0 ; ));
(0, $($program:tt),* ; $_head:tt, $($tail:tt),*)
=> …
Run Code Online (Sandbox Code Playgroud) fn main() {
let arr: [u8;8] = [97, 112, 112, 108, 101];
println!("Len is {}",arr.len());
println!("Elements are {:?}",arr);
}
Run Code Online (Sandbox Code Playgroud)
fn main() {
let arr: [u8;8] = [97, 112, 112, 108, 101];
println!("Len is {}",arr.len());
println!("Elements are {:?}",arr);
}
Run Code Online (Sandbox Code Playgroud)
有什么办法可以用0来填充剩余的元素吗?就像是:
let arr: [u8;8] = [97, 112, 112, 108, 101].something();
Run Code Online (Sandbox Code Playgroud) 如何在 Rust 中定义一个公共结构,其中所有字段都是公共的,而不必pub
在每个字段前重复修饰符?
一个pub_struct
宏将是理想的:
pub_struct! Foo {
a: i32,
b: f64,
// ...
}
Run Code Online (Sandbox Code Playgroud)
这相当于:
pub struct Foo {
pub a: i32,
pub b: f64,
//...
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试建立一个进行一些代码转换的宏,并且应该能够解析其自身的语法。这是我能想到的最简单的例子:
replace!(x, y, x * 100 + z) ~> y * 100 + z
Run Code Online (Sandbox Code Playgroud)
此宏应该能够用作为第三参数提供的表达式中的第二个标识符替换第一个标识符。宏应该对第三个参数的语言有所了解(在我的特定情况下,与示例相反,它不会在Rust中解析),并对其进行递归应用。
在Rust中构建此类宏的最有效方法是什么?我知道这种proc_macro
方法和macro_rules!
一种方法。但是我不确定是否macro_rules!
足够强大来处理此问题,并且找不到如何使用来构建自己的转换的文档proc_macro
。谁能指出我正确的方向?