标签: rust-macros

导出使用 crate 中定义的函数的声明性宏

我正在尝试导出一个使用包中定义的某些函数的宏。像这样的东西,例如在一个名为的板条箱中a_macro_a_day

// lib.rs

pub fn a() {}

#[macro_export]
macro_rules! impl_helper_funcs {
  use crate::a; // error unresolved import
  use a_macro_a_day::a; // error unresolved import
  fn b() {
    ...
    a() // call imported a here
  }
}
Run Code Online (Sandbox Code Playgroud)

我尝试过使用各种组合use来导入a,但错误总是显示宏定义为unresolved import crateor unresolved import a_macro_a_day

我不想采用过程宏方式,因为这只是为了减少代码重复。有没有办法导出导入本地(但公共)函数的宏?

macros rust rust-crates rust-macros

3
推荐指数
1
解决办法
859
查看次数

emacs/spacemacs是否支持嵌入在Rust Macro中的嵌套C++模式?

参考:rust-cpp

emacs/spacemacs可以在主模式下支持嵌套模式吗?我习惯于对emacs/spacemacs进行vim和new.

emacs macros rust spacemacs rust-macros

2
推荐指数
1
解决办法
177
查看次数

打印!宏按顺序执行

我的部分代码如下所示:

print_usage_instructions();
print!("Command: ");
let stdin = io::stdin();
let mut line = String::new();
stdin.lock().read_line(&mut line).expect("Couldn't process the command.");
println!("{}", line);
Run Code Online (Sandbox Code Playgroud)

我期望的行为是这样的:

Usage instructions and stuff
Command: [my command]
[my command]
Run Code Online (Sandbox Code Playgroud)

但是,会发生什么:

Usage instructions and stuff
[my command]
Command: [my command]
Run Code Online (Sandbox Code Playgroud)

任何想法为什么会发生?AFAIK,编译器没有理由在这里更改执行顺序,这部分代码不是异步也不是多线程.

rust rust-macros

2
推荐指数
1
解决办法
100
查看次数

同时创建宏以定义可变变量的“预期标识符”

我想同时声明多个可变变量。定义了一个宏来声明可变变量,如下所示。

macro_rules! mutf64 {
    ( $( $e:expr ),+ ) => {
        {
            $(
                let mut $e:f64;
            )+
        }
    };
}

fn main() {
    mutf64!(FT, FX, alpha, H, K, lambda, T, X);
}
Run Code Online (Sandbox Code Playgroud)

使用编译器进行语法检查时出现错误:

macro_rules! mutf64 {
    ( $( $e:expr ),+ ) => {
        {
            $(
                let mut $e:f64;
            )+
        }
    };
}

fn main() {
    mutf64!(FT, FX, alpha, H, K, lambda, T, X);
}
Run Code Online (Sandbox Code Playgroud)

我为什么不能这样做macro_rules

rust rust-macros

2
推荐指数
1
解决办法
233
查看次数

如何为特征的每个实现自动生成递增的数字标识符?

我有一个Component特征,该特征具有返回索引的方法,如下所示:

trait Component {
    fn index(&self) -> usize;
}
Run Code Online (Sandbox Code Playgroud)

这些索引用于在位集中设置标志。例如,Component返回索引为5 的特征对象将导致在容器中设置第5位。

目前,我为每种实现类型手动返回运行索引:

struct Foo;
struct Bar;

impl Component for Foo {
    fn index(&self) -> usize { 0 }
}

impl Component for Bar {
    fn index(&self) -> usize { 1 }
}
Run Code Online (Sandbox Code Playgroud)

特质对象插入到容器中,该容器使用位集跟踪添加的组件:

struct Container<'a> {
    components: Vec<Component + 'a>,
    bits: BitSet
}

impl<'a> Container<'a> {
    fn add<T: Component + 'a>(&mut self, component: T) {
        self.components.push(component);
        self.bits.set(component.index());
    }
}
Run Code Online (Sandbox Code Playgroud)

这可以正常工作,但是手动返回每种实现类型的索引很麻烦。我怎样才能使每种实现类型都自动获得其索引?

rust rust-macros

2
推荐指数
1
解决办法
121
查看次数

Rust 宏计算并生成重复的结构字段

我想编写一个宏,从整数参数生成不同的结构。例如,make_struct!(3)可能会生成如下内容:

pub struct MyStruct3 {
    field_0: u32,
    field_1: u32,
    field_2: u32
}
Run Code Online (Sandbox Code Playgroud)

将“3”文字转换为可用于生成代码的数字的最佳方法是什么?我应该使用macro_rules!还是proc-macro

rust rust-macros

2
推荐指数
1
解决办法
2443
查看次数

如何处理或测试某个类型是否是 Rust 宏中的选项?

我正在尝试创建一个宏来生成一个可以从 postgres 数据库填充的结构。现在,由于数据库中存在可为空和不可为空的字段,我希望在宏中以不同的方式处理它们。

输出应该是这样的结构:

#[derive(Debug, Default)]
pub struct MyStruct {
    pub attrib_a: i64,
    pub attrib_b: Option<i64>,
}

impl MyStruct {
    pub fn get_row(&self, row: &postgres::rows::Row) -> MyStruct {
        MyStruct {
            // the non-nullable attrib_a, where I can for sure take the value out of the Option and assign it
            attrib_a: match row.get::<_, Option<i64>>("attrib_a") {
                Some(x) => x,
                None => 0,
            },

            // here for the nullable attrib_b I just want to return the Option as is
            attrib_b: row.get::<_, Option<i64>>("attrib_b"),
        } …
Run Code Online (Sandbox Code Playgroud)

rust rust-macros

2
推荐指数
1
解决办法
1989
查看次数

为什么我得到“无法在此范围内派生宏”?

尝试cargo build针对此代码:

#![allow(unused)]

use serde::{Deserialize, Serialize};
use serde_json::{Result, Value};

#[derive(Serialize, Deserialize,Debug)]
struct Repository{
    r#type: String,
    url: String,
}

fn main() {
    println!("Hello, world!");
}
Run Code Online (Sandbox Code Playgroud)

这是 cargo.toml 文件:

[package]
name = "demo_err"
version = "0.1.0"
authors = ["Onorio Catenacci <catenacci@ieee.org>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde = "1.0.104"
serde_json = "1.0.44"
Run Code Online (Sandbox Code Playgroud)

当然,我的真实代码要大一些,但这是我可以重现错误的最小代码。

我收到以下错误:

   Compiling demo_err v0.1.0 (U:\skunkworks\rust\demo_err)
error: cannot find derive macro `Serialize` in this scope
 --> src\main.rs:9:10
  |
9 | …
Run Code Online (Sandbox Code Playgroud)

rust serde rust-macros

2
推荐指数
1
解决办法
1252
查看次数

程序宏可以作为函数进行调试吗?

我正在尝试在我正在使用的库中调试复杂的程序宏。

由于我不能使用带有宏的调试器,并且各种宏扩展工具在这里被证明是无用的,我正在寻找替代方案。

程序宏是否可以像经过适当调试的函数一样运行?我想象将结果存储proc_macro::TokenStream在一个变量中。

rust rust-macros rust-proc-macros

2
推荐指数
1
解决办法
363
查看次数

是否可以仅使用 `macro_rules!` 来实现这个宏?

我正在尝试制作一个宏,让我遍历类型列表以减少 trait impl 样板。(我目前正在使用不同的基于宏的解决方案,但这似乎更具可读性,如果可以不添加依赖项的话。)

这是我的目标语法:

trait MyTrait {}

tfor! {
    for Ty in [i32, u32] {
        impl MyTrait for Ty {}
    }
}
Run Code Online (Sandbox Code Playgroud)

我的尝试:

macro_rules! tfor {
    (for $ty:ident in [$($typ:ident),*] $tt:tt) => {
        $(
            type $ty = $typ;
            tfor! { @extract $tt }
        )*
    };
    (@extract { $($tt:tt)* }) => {
        $($tt)*
    };
}
Run Code Online (Sandbox Code Playgroud)

这会产生错误,因为两次迭代都定义了Ty在同一范围内命名的类型:

   |
4  |               type $ty = $typ;
   |               ^^^^^^^^^^^^^^^^
   |               |
   |               `Ty` redefined here
   |               previous definition of the type `Ty` …
Run Code Online (Sandbox Code Playgroud)

rust rust-macros

2
推荐指数
1
解决办法
81
查看次数