首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有可能吗?锈蚀宏定义了一堆常量?

有可能吗?锈蚀宏定义了一堆常量?
EN

Stack Overflow用户
提问于 2022-03-11 18:40:02
回答 1查看 731关注 0票数 1

让我们假设,我们需要一串常量,将棋盘的每个方格与它的坐标相关联,这样我们就可以在我们的锈蚀代码中使用这些常量。

这样的定义之一可以是:

代码语言:javascript
复制
#[allow(dead_code)]
const A1: (usize,usize) = (0, 0);

就会有64人。

现在,作为emacs用户,我可以轻松地生成源代码,例如:

代码语言:javascript
复制
(dolist (col '(?A ?B ?C ?D ?E ?F ?G ?H))
  (dolist (row '(?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8))
    (insert "#[allow(dead_code)]")
    (end-of-line)
    (newline-and-indent)
    (insert "const " col row ": (usize,usize) = ("
        (format "%d" (- col ?A))
        ", "
        (format "%d" (- row ?1))
        ");")
    (end-of-line)
    (newline-and-indent)))

有了缺点,现在我的文件增加了128条特别无聊的行。

在通用Lisp中,我会通过定义宏来解决这个问题,例如:

代码语言:javascript
复制
(defmacro defconst-square-names ()
       (labels ((square-name (row col)
              (intern 
               (format nil "+~C~D+" 
                   (code-char (+ (char-code #\A) col))
                   (+ row 1))))
            (one-square (row col)
              `(defconstant ,(square-name row col)
             (cons ,row ,col))))
         `(eval-when (:compile-toplevel :load-toplevel :execute)
        ,@(loop
           for col below 8
           appending 
           (loop for row below 8
             collecting (one-square row col))))))
(defconst-square-names) ;; nicer packaging of those 64 boring lines...

现在,问题出现了,当然,

如果

  • 宏系统能够做到这一点?
  • 能显示这样的宏吗?
  • ,我看过了,您需要把这样的Rust宏放到一个单独的板条箱里还是什么东西?!

更新

@aedm用关于seq-macro板条箱的评论向我指出了我第一次尝试完成它。但是不幸的是,在浏览有关宏的各种Rust文档之后,我仍然不知道如何在这样一个宏中定义和调用编译时函数:

代码语言:javascript
复制
fn const_name(index:usize) -> String {
  format!("{}{}",
      char::from_u32('A' as u32
             + (index as u32 % 8)).unwrap()
      , index / 8)
}

seq!(index in 0..64 {
  #[allow(dead_code)]
  const $crate::const_name(index) : (usize,usize) = ($(index / 8), $(index %8));
});

在我的Common解决方案中,我只是在宏中定义了本地函数来完成这些工作。生锈的方式是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-12 00:41:21

这里有一种只使用macro_rules! (“宏示例”)和paste机箱(构造标识符)的方法。它不是特别优雅,但它相当短,不需要您编写一个proc宏机箱。

由于macro_rules!不会算术,所以需要使用所有涉及的符号来调用它。(也许seq-macro会在这方面有所帮助,但我并不熟悉。)

代码语言:javascript
复制
use paste::paste;

macro_rules! board {
    // For each column, call column!() passing the details of that column
    // and all of the rows. (This can't be done in one macro because macro
    // repetition works like "zip", not like "cartesian product".)
    ( ($($cols:ident $colnos:literal),*), $rows:tt ) => {
        $( column!($cols, $colnos, $rows); )*
    };
}

/// Helper for board!
macro_rules! column {
    ( $col:ident, $colno:literal, ($($rows:literal),*) ) => {
        $(
            paste! {
                // [< >] are special brackets that tell the `paste!` macro to
                // paste together all the pieces appearing within them into
                // a single identifier.
                #[allow(dead_code)]
                const [< $col $rows >]: (usize, usize) = ($colno, $rows - 1);
            }
        )*
    };
}

board!((A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7), (1, 2, 3, 4, 5, 6, 7, 8));

fn main() {
    dbg!(A1, A8, H1, H8);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71443259

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档