Helix-hashmap! 宏 解析

本贴最后更新于 205 天前,其中的信息可能已经事过境迁

hashmap!

#[macro_export]
macro_rules! hashmap {
    (@single $($x:tt)*) => (());
    (@count $($rest:expr),*) => (<[()]>::len(&[$(hashmap!(@single $rest)),*]));

    ($($key:expr => $value:expr,)+) => { hashmap!($($key => $value),+) };
    ($($key:expr => $value:expr),*) => {
        {
            let _cap = hashmap!(@count $($key),*);
            let mut _map = ::std::collections::HashMap::with_capacity(_cap);
            $(
                let _ = _map.insert($key, $value);
            )*
            _map
        }
    };
}

  1. 宏属性

    • #[macro_export]​:这个属性使得宏可以在定义它的 crate 外部使用。
  2. 内部辅助宏

    • (@single $($x:tt)*) => (());​:这是一个内部宏规则,它匹配任何 Token 树(tt​)并返回一个空元组。这个规则似乎没有实际作用,可能是为了占位或调试。
    • (@count $($rest:expr),*) => (<[()]>::len(&[rest)),*]));​:这是另一个内部宏规则,用于计算宏调用中提供的表达式数量。它通过生成一个元组数组并计算其长度来实现。
  3. 外部宏规则

    • (key:expr => (value),+) };​:这个规则处理以逗号结尾的键值对列表。它是一个重复规则,允许宏调用者提供多个键值对。
    • (key:expr => $value:expr),*) => { ... };​:这个规则处理不以逗号结尾的键值对列表。它计算键的数量,初始化一个具有适当容量的 HashMap​,然后将每个键值对插入到 HashMap​中。
  4. HashMap 初始化

    • let _cap = hashmap!(@count key),*);​:使用 @count​内部宏规则来确定宏调用中提供的键的数量。
    • let mut _map = ::std::collections::HashMap::with_capacity(_cap);​:根据计算出的键的数量来初始化 HashMap​的容量。
    • key, $value);)*​:遍历所有键值对,并将它们插入到 HashMap​中。

使用示例

use std::collections::HashMap;

fn main() {
    let mut map = hashmap!(
        "key1" => 1,
        "key2" => 2,
        "key3" => 3,
    );

    assert_eq!(map.len(), 3);
    assert_eq!(map["key1"], 1);
    assert_eq!(map["key2"], 2);
    assert_eq!(map["key3"], 3);
}

执行上述宏调用. 首先匹配 ,​结尾的几个部分

 "key1" => 1,
 "key2" => 2,
 "key3" => 3,

对每个部分,再次调用 hashmap!($($key => $value),+)​ 这一次调用的就不再包含 ,​,所以会去执行另一个分支

fn main(){
    // let _cap = hashmap!(@count $($key),*);
	// Note: 这里会调用内部辅助宏.
    let _cap = hashmap!(@count "key1", "key2", "key3");
	// let mut _map = ::std::collections::HashMap::with_capacity(_cap);
	let mut _map= HashMap::with_capacity(_cap);
    //$(
    //   let _ = _map.insert($key, $value);
    //)*
	// 重复执行三次上述片段
	let _ = _map.insert("key1",1);
	let _ = _map.insert("key2",2);
	let _ = _map.insert("key3",3);
	return _map
}

然后,对上述的执行结果,再次执行内部辅助宏 @count

(@count $($rest:expr),*) => (<[()]>::len(&[$(hashmap!(@single $rest)),*]));
  • (<[()]>::len(&[$(hashmap!(@single $rest)),*])​ 是宏展开的代码。这里使用了 Rust 的数组和类型推断机制来计算参数的数量。

    • <[()]>::len(&[...])​ 是一个类型推断的技巧,它创建了一个空元组 ()​ 的数组,并调用 .len()​ 方法来获取数组的长度。
    • $(hashmap!(@single $rest)),* ​ 是一个重复的宏调用,对于每个 $rest​ 表达式,它都会调用 hashmap!(@single ...) ​ 宏。

最后的生成结果如下:

fn main() {
    //let _cap = hashmap!(@count "key1", "key2", "key3");
	let _cap = <[()]>::len(&[((),), ()]);
	// _cap = 3
}

<[()]>​是用于类型推断的语法,它指示编译器去推断数组的类型。这里的 <[()]>​并不是指一个数组字面量,而是一种特殊的语法结构,称为类型参数推断(type hint)。

具体来说,<[()]>​告诉编译器,我们想要一个数组,其元素类型为 ()​(空元组),并且希望编译器根据上下文推断出数组的具体类型。在这个例子中,.len()​方法需要一个数组引用作为参数,而 <[()]>​就是用来提供这个数组引用的类型信息

  • Rust

    Rust 是一门赋予每个人构建可靠且高效软件能力的语言。Rust 由 Mozilla 开发,最早发布于 2014 年 9 月。

    58 引用 • 22 回帖
  • Helix-editor
    1 引用

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
crowds21
不带评论的观察是人类智力的最高形式 北京

推荐标签 标签

  • 正则表达式

    正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列遵循某个句法规则的字符串。

    31 引用 • 94 回帖
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有计划重制上线。

    14 引用 • 257 回帖
  • DNSPod

    DNSPod 建立于 2006 年 3 月份,是一款免费智能 DNS 产品。 DNSPod 可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。

    6 引用 • 26 回帖 • 519 关注
  • FFmpeg

    FFmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。

    23 引用 • 32 回帖 • 1 关注
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    78 引用 • 391 回帖 • 1 关注
  • QQ

    1999 年 2 月腾讯正式推出“腾讯 QQ”,在线用户由 1999 年的 2 人(马化腾和张志东)到现在已经发展到上亿用户了,在线人数超过一亿,是目前使用最广泛的聊天软件之一。

    45 引用 • 557 回帖 • 42 关注
  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    5 引用 • 18 回帖 • 173 关注
  • abitmean

    有点意思就行了

    29 关注
  • WiFiDog

    WiFiDog 是一套开源的无线热点认证管理工具,主要功能包括:位置相关的内容递送;用户认证和授权;集中式网络监控。

    1 引用 • 7 回帖 • 593 关注
  • Windows

    Microsoft Windows 是美国微软公司研发的一套操作系统,它问世于 1985 年,起初仅仅是 Microsoft-DOS 模拟环境,后续的系统版本由于微软不断的更新升级,不但易用,也慢慢的成为家家户户人们最喜爱的操作系统。

    223 引用 • 474 回帖
  • FlowUs

    FlowUs.息流 个人及团队的新一代生产力工具。

    让复杂的信息管理更轻松、自由、充满创意。

    1 引用 • 1 关注
  • ngrok

    ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。

    7 引用 • 63 回帖 • 627 关注
  • V2Ray
    1 引用 • 15 回帖
  • Logseq

    Logseq 是一个隐私优先、开源的知识库工具。

    Logseq is a joyful, open-source outliner that works on top of local plain-text Markdown and Org-mode files. Use it to write, organize and share your thoughts, keep your to-do list, and build your own digital garden.

    6 引用 • 63 回帖 • 4 关注
  • Flume

    Flume 是一套分布式的、可靠的,可用于有效地收集、聚合和搬运大量日志数据的服务架构。

    9 引用 • 6 回帖 • 639 关注
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    497 引用 • 1388 回帖 • 278 关注
  • PostgreSQL

    PostgreSQL 是一款功能强大的企业级数据库系统,在 BSD 开源许可证下发布。

    22 引用 • 22 回帖 • 3 关注
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    83 引用 • 37 回帖 • 1 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    575 引用 • 3533 回帖
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    75 引用 • 258 回帖 • 623 关注
  • FreeMarker

    FreeMarker 是一款好用且功能强大的 Java 模版引擎。

    23 引用 • 20 回帖 • 465 关注
  • 宕机

    宕机,多指一些网站、游戏、网络应用等服务器一种区别于正常运行的状态,也叫“Down 机”、“当机”或“死机”。宕机状态不仅仅是指服务器“挂掉了”、“死机了”状态,也包括服务器假死、停用、关闭等一些原因而导致出现的不能够正常运行的状态。

    13 引用 • 82 回帖 • 59 关注
  • 深度学习

    深度学习(Deep Learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

    53 引用 • 40 回帖
  • 链滴

    链滴是一个记录生活的地方。

    记录生活,连接点滴

    157 引用 • 3798 回帖
  • RESTful

    一种软件架构设计风格而不是标准,提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    30 引用 • 114 回帖 • 2 关注
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    30 引用 • 96 回帖
  • Chrome

    Chrome 又称 Google 浏览器,是一个由谷歌公司开发的网页浏览器。该浏览器是基于其他开源软件所编写,包括 WebKit,目标是提升稳定性、速度和安全性,并创造出简单且有效率的使用者界面。

    62 引用 • 289 回帖