Helix-hashmap! 宏 解析

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

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 月。

    59 引用 • 22 回帖 • 10 关注
  • Helix-editor
    1 引用

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • 酷鸟浏览器

    安全 · 稳定 · 快速
    为跨境从业人员提供专业的跨境浏览器

    3 引用 • 59 回帖 • 48 关注
  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖 • 1 关注
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 679 关注
  • 机器学习

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

    77 引用 • 37 回帖 • 1 关注
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    108 引用 • 153 回帖 • 3 关注
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    32 引用 • 108 回帖
  • WebComponents

    Web Components 是 W3C 定义的标准,它给了前端开发者扩展浏览器标签的能力,可以方便地定制可复用组件,更好的进行模块化开发,解放了前端开发者的生产力。

    1 引用 • 11 关注
  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    12 引用 • 5 回帖 • 632 关注
  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    56 引用 • 85 回帖
  • ReactiveX

    ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的 API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。

    1 引用 • 2 回帖 • 178 关注
  • Laravel

    Laravel 是一套简洁、优雅的 PHP Web 开发框架。它采用 MVC 设计,是一款崇尚开发效率的全栈框架。

    19 引用 • 23 回帖 • 740 关注
  • 房星科技

    房星网,我们不和没有钱的程序员谈理想,我们要让程序员又有理想又有钱。我们有雄厚的房地产行业线下资源,遍布昆明全城的 100 家门店、四千地产经纪人是我们坚实的后盾。

    6 引用 • 141 回帖 • 608 关注
  • 代码片段

    代码片段分为 CSS 与 JS 两种代码,添加在 [设置 - 外观 - 代码片段] 中,这些代码会在思源笔记加载时自动执行,用于改善笔记的样式或功能。

    用户在该标签下分享代码片段时需在帖子标题前添加 [css] [js] 用于区分代码片段类型。

    197 引用 • 1412 回帖
  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    76 引用 • 1742 回帖 • 6 关注
  • 以太坊

    以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统。以太坊是一个平台和一种编程语言 Solidity,使开发人员能够建立和发布下一代去中心化应用。 以太坊可以用来编程、分散、担保和交易任何事物:投票、域名、金融交易所、众筹、公司管理、合同和知识产权等等。

    34 引用 • 367 回帖 • 2 关注
  • TensorFlow

    TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。

    20 引用 • 19 回帖 • 4 关注
  • ActiveMQ

    ActiveMQ 是 Apache 旗下的一款开源消息总线系统,它完整实现了 JMS 规范,是一个企业级的消息中间件。

    19 引用 • 13 回帖 • 683 关注
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    22 引用 • 148 回帖 • 9 关注
  • 友情链接

    确认过眼神后的灵魂连接,站在链在!

    24 引用 • 373 回帖
  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    414 引用 • 3592 回帖
  • V2Ray
    1 引用 • 15 回帖 • 4 关注
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖 • 9 关注
  • 正则表达式

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

    31 引用 • 94 回帖
  • 书籍

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

    82 引用 • 412 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3201 引用 • 8217 回帖 • 2 关注
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    61 引用 • 29 回帖 • 10 关注
  • wolai

    我来 wolai:不仅仅是未来的云端笔记!

    2 引用 • 14 回帖 • 2 关注