Rust 宏:根据表达式调用函数

2024-02-11

我有三个不同的函数,我想根据宏参数调用其中一个函数。这个参数应该被预处理,这就是为什么我认为我需要把它写成expr。但是,我似乎找不到一种方法来区分不同的情况expr在宏中。这是我的代码:

fn func_100(){
    println!("Func 100!");
}
fn func_200(){
    println!("Func 200!");
}
fn func_300(){
    println!("Func 300!");
}

macro_rules! generate_func_call {
    (100) => {
        func_100();
    };
    (200) => {
        func_200();
    };
    (300) => {
        func_300();
    }
}

macro_rules! generate_func_call_wrapper {
    ($func: ident, $number: expr) => {
        fn $func(){
            println!("{:?}", $number / 100);
            generate_func_call!($number);
        }
    };
}

generate_func_call_wrapper!(f1,100);
generate_func_call_wrapper!(f2,200);
generate_func_call_wrapper!(f3,300);

fn main(){
    f1();
}

这会生成以下编译时错误:

    generate_func_call!($number);
                        ^^^^^^^ no rules expected this token in macro call

我怎样才能修复这个程序,以便根据$number表达?


您可以通过调用来查看宏扩展cargo +nightly rustc --profile=check -- -Zunstable-options --pretty=expanded或使用货物扩展 https://github.com/dtolnay/cargo-expand

fn f1() {
    {
        ::std::io::_print(::std::fmt::Arguments::new_v1(
            &["", "\n"],
            &match (&(100 / 100),) {
                (arg0,) => [::std::fmt::ArgumentV1::new(arg0, ::std::fmt::Debug::fmt)],
            },
        ));
    };
    ();
}

你可以看到最后一个();本来应该是func_100()

这是因为没有令牌规则generate_func_call类型的($number: expr)是。没有匹配扩展的规则。这是因为$number没有被取代100正如您在函数中所期望的那样。该宏只是根据以下内容创建更多 Rust 代码片段类型 https://doc.rust-lang.org/reference/macros-by-example.html它接收,它不会尝试评估任何东西。

将代码更改为:

macro_rules! generate_func_call {
    ($number: expr) => {
        match $number {
            100 => func_100(),
            200 => func_200(),
            300 => func_300(),
            _ => (),
        }
    };
}

最后();更改为:

match 300 {
    100 => func_100(),
    200 => func_200(),
    300 => func_300(),
    _ => (),
};

您不必担心额外的跳转语句等,它已被优化为300是编译时间常数。它只是变成func_300().

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Rust 宏:根据表达式调用函数 的相关文章

随机推荐

  • 哪种排序算法可提供最佳的最坏情况性能?

    对于绝对最坏的情况 最快的已知排序算法是什么 我不关心最好的情况 并且假设有一个巨大的数据集 如果这很重要的话 确保你已经看到这个 可视化排序算法 http www sorting algorithms com 它帮助我决定使用哪种算法
  • Php PDO 函数:lastInsertId 的安全性如何?

    我对 Php PDO 函数 lastInsertID 没有什么困惑 如果我理解正确的话 它会返回插入数据库的最后一个自动增量ID 当我创建注册用户的功能时 当我执行在数据库中插入用户的查询时 我通常会使用此函数 我的问题是 例如 我有一百个
  • 设置JAVA_HOME和JRE_HOME路径

    我被分配了一个 Linux 机器 里面有 java 可用 java version java version 1 7 0 09 icedtea OpenJDK Runtime Environment rhel 2 3 4 1 el6 3 x
  • twitter4j - 如何配置?

    我正在尝试使用编写一个简单的 Twitter 客户端推特4j http twitter4j org 但我似乎无法完成第一步 配置参数 有一个配置页 http twitter4j org en configuration html在网站上说我
  • 我应该在 EDT 中分配/创建 swing 元素吗?

    我应该在 EDT 中创建 swing 元素吗 我在编辑非线程安全图形元素时遇到了并发问题 但我正在创建它们 但它们尚未显示 如果它们很多或需要一些时间来分配 这会冻结 GUI 但不会是吗 下面是我使用 EDT 来显示但不创建 GUI 结构的
  • React-Native:更改 ImageBackground 的不透明度颜色

    我一直在尝试开发下面提到的屏幕 为此 我创建了以下组件 import React Component from react import View Text StyleSheet ImageBackground Image from rea
  • 如何在 ReactiveCocoa 4 中创建自定义信号?

    我有以下设置 GridView包括GridViewCells GridView class GridView UIView var gridViewCells GridViewCell let tapHandler Position gt
  • 分配 RAM 在任务管理器中显示 RAM 使用量的两倍

    进行一些分析 内存和速度 我对 win7 似乎分配的 RAM 恰好是我要求的两倍这一事实感到震惊 请注意 这是我第一次在 win7 上进行此类主动分析 所以我不这样做我真的不知道会发生什么 我在 win7 64 位 下使用 MSVC 的 E
  • 在协程 close() 上运行代码

    我正在编写大量使用协程的代码 并且我希望在关闭时有可靠的行为 假设我有一个协程和一个上下文管理器 from contextlib import contextmanager contextmanager def print context
  • 在 Java 中向大字符串添加前导零

    我目前正在用 Java 制作一个拍卖程序 我正在尝试计算截止日期 但是我的日期一直显示为 7 04 2013 11 22 有没有办法使用 String format 添加前导零到今天为止什么时候是一位数的日期 String timeOne
  • 如何全局定义套接字变量

    我的里面有这段代码socketio文件 在这里我可以使用socket simply import from lodash import mongoose from mongoose exports register server optio
  • Twitterizer - 远程服务器返回错误:(401) 未经授权

    我正在关注瑞奇的Twitter 示例 https stackoverflow com questions 8003959 mvc3 c sharp beginner in twitterizer how to logon user via
  • 以编程方式在 Woocommerce 中创建新订单

    我在 WooCommerce 中以编程方式创建订单时遇到了最困难的时间 我正在使用下面的代码 并且确实创建了订单 但我无法获取添加到订单中的客户信息或产品系列项目 创建的新订单只是作为访客 没有商品 用户信息等 问题似乎是 一旦创建了订单对
  • Node.Js 错误“请求中不存在‘Access-Control-Allow-Origin’标头”

    这个问题和其他问题类似 然而 有一个差异使得它为什么不起作用非常令人困惑 我的 JavaScript 正在调用 6 个 json 文件 并且所有文件都工作正常 在 Node JS 中 我设置了 cors 和 headers 如下所示 var
  • refs 是否应该列为 useEffect 等的依赖项?

    据我了解 useRef 返回的容器始终相同 但在 useEffect 和类似函数中引用它们会导致 eslint exhausive deps 警告 在这种情况下忽略警告是否安全 有什么好方法可以避免警告堵塞输出日志以及禁用行注释堵塞我的代码
  • 使用 python libclang 检索评论

    在下面的头文件中我想得到相应的 reflect对类和成员变量的注释 ifndef HEADER FOO define HEADER FOO reflect class Foo public private int m int reflect
  • 了解模运算符

    我有一些代码循环遍历列表元素的集合和颜色的集合 它确保每个列表元素都指定有一种颜色 除了模数运算符之外 我了解有关此的所有内容 我知道它找到并使用剩余的数字 但我一生都无法理解它在做什么here var li document getEle
  • 如何更改 JFileChooser 中的默认 java 图标

    我想改变内置的java图标JFileChooser JFrame类有一个setIconImage 设置图标的方法 但我找不到类似的东西JFileChooser 无需更换咖啡杯 任何人都可以轻松识别出我的软件是用 java 编写的 谁能帮助我
  • Rails 和 RSpec:在不同命名空间(模块)中测试具有相同名称的控制器

    我有使用 RSpec 3 4 0 测试的 Rails 4 1 16 API 应用程序 并且在测试不同模块中调用相同名称的类时遇到问题 结构是 app controllers bar notifications controller rb c
  • Rust 宏:根据表达式调用函数

    我有三个不同的函数 我想根据宏参数调用其中一个函数 这个参数应该被预处理 这就是为什么我认为我需要把它写成expr 但是 我似乎找不到一种方法来区分不同的情况expr在宏中 这是我的代码 fn func 100 println Func 1