max std value 宏_Rust Macro/宏 新手指南

Rust语言最强大的一个特点就是可以创建和利用宏/Macro。不过创建 Rust宏看起来挺复杂,常常令刚接触Rust的开发者心生畏惧。这片文章 的目的就是帮助你理解Rust Macro的基本运作原理,学习如何创建自己的 Rust宏。

相关链接:在线学编程 - 汇智网

1、什么是Rust的宏/Macro?

b71689a2d35ff5e5d77d456eb02d3252.png

如果你尝试过Rust,应该已经用过Rust的宏了:println!。这个宏 可以在终端输出一行文本,并且支持变量的插值。

简单地说,Rust宏让你可以发明自己的语法,编写出可以自行展开的代码, 也就是我们通常所说的元编程,你甚至可以用Rust宏来创作自己的DSL。

Rust宏的基本运作机制就是:首先匹配宏规则中定义的模式,然后将匹配 结果绑定到变量,最后展开变量替换后的代码。

不理解也没有关系,让我们继续看。

2、如果创建Rust宏/Macro?

可以使用Rust预置的macro_rules!宏来创建一个新的Rust宏。

下图展示了如何创建一个空白的Rust宏:hey!,这个宏什么功能 也没有,我们现在只关注它的结构:

016100e2f96eaf725f53b3098fd125f5.png

() => {}看起来很神秘,因为它不是标准的rust语法,是macro_rules! 这个宏自己发明的,用来表示一条宏规则,=>左边是匹配模式,右边是 等待展开的代码:

7f1631d060eee0b589a141df3a74d9bc.png

左边的小括号部分是Rust宏的匹配器/Matcher,用来匹配模式并捕捉变量,这是我们 发明自定义语法和DSL的关键所在。

右边的大括号部分是Rust宏的转码器/Transcriber,也就是我们要应用匹配器捕捉到 的变量的部分,Rust编译器将利用变量和这部分的代码来生成实际的Rust代码。

类似于Rust中的match语句,在macro_rules!中可以定义多条宏规则,例如:

macro_rules! hey{      () => {},     () => {}}

3、模式匹配与变量捕捉

现在我们看看Rust宏的模式是如何匹配的。

fea9dc9ebabb528fb0dfe05ba29ff9d4.png

在匹配器/Matcher中,$name部分定义了变量名,匹配结果将绑定到该变量以便 应用到转码器/Transcriber中。在这个示例中,表示我们将Rust宏的匹配结果存入变量$name。

冒号后面的部分被称为选择器/Designator,用于声明我们要匹配的类型。 例如在这个示例中,我们使用的是表达式选择器,也就是expr, 这告诉Rust:匹配一个表达式,然后存入$name变量。

表达式选择器只是Rust中众多可用选择器中的一个,下面是一些常见的 Rust宏选择器:

  • item:条目,例如函数、结构、模块等
  • block:代码块
  • stmt:语句
  • pat:模式
  • expr:表达式
  • ty:类型
  • ident:标识符
  • path:路径,例如 foo、 ::std::mem::replace, transmute::<_ int>, …
  • meta:元信息条目,例如 #[…]和 #![rust macro…] 属性
  • tt:词条树

那么,现在如何在转码器/Transcriber中应用我们捕捉到的变量?

6c30b6a0ca8a01218d24ac095b77b9b8.png

很简单,在Rust宏转码器部分我们只需要在常规的Rust代码中,嵌入匹配器 捕捉到的变量就行了,没什么特别之处!

4、编写第一个Rust宏

我们已经了解了如何编写一个Rust宏,现在让我们动手写一个:

7bf54cb7ad62379073c18c561546f6e3.png

很简单,对吧?

5、重复模式的提取与利用

我们用的许多Rust宏都可以支持非常多的输入。以vec!宏为例,我们 可以这样调用它:vec![rust macro1,2,3,4,5],或者这样:vec![rust macro1,2,3,,4,5,6,7,8]。

那么vec!宏是如何实现这一点的?很显然它不会去定义成千上万个变量来 逐个保存匹配结果,秘密在于重复模式的匹配:

12379f2cc23963e96edb73deb37496bb.png

我们只需要把希望重复的模式写在$(...)这部分,然后插入分隔符, 在这里也就是逗号,最后添加一个*符号,表示重复匹配$()中的模式。

还有点晕?让我们看个具体的例子:

a2b32574dda9a9f25d991dc9436ca17e.png

在这个示例中,对于hey!宏,我们重复捕捉输入表达式并存入变量$name, 也就是说,所有捕捉到的表达式都绑定到变量$name了 —— 不妨把 $name 想象成数组变量。

6、用重复模式在Rust中实现Ruby的哈希表语法

如果你之前写过Ruby程序,可能还记得在Ruby中定义哈希表的语法:key => value。 现在我们可以用Rust宏来在Rust中实现哈希表的这种定义方法!

22b4884ddd544f9a1f3b8f51efc4b528.png

在Rust宏的匹配器部分,我们使用模式$key:expr => $value:expr 来分别捕捉$key和$value表达式,分隔符为=>。 不过现在只能匹配一个键/值对,但是哈希表通常都是多个键值对的。应该 如何实现?

答案是使用重复匹配:

12e61d15e4fab0f2c1824bcb1f4455bd.png

将我们要匹配的键/值对模式放到$(),*,就可以进行重复匹配了。COOL!!

a7f71aab5faf00099054e5b5ac6a933a.png

那么,如何应用捕捉到的键/值对?显然,我们应该在Rust宏的转码器中创建哈希表对象, 然后将捕捉到的所有键值对插入该哈希表:

a63a12485f5a5dee461703fb16484e3b.png

在转码器中,注意代码中的$()*,它的意思是其中的代码会重复展开!

15ab3cea62cee5c63b48cd33ebaad10d.png

就像你看到的,当我们调用map!("name" => "Finn", "gender" => "Boy")时, 我们在生成两段重复的代码。

key => value将被转码为在Rust宏的转码器/transcriber中指定的代码,也就是 hm.insert($key, $value),其中$key和$value是我们在Rust宏的匹配器部分 捕捉到的变量。

好了,让我们看看完整的map!宏实现:

11adaf63f6707a4d6fd33a5807632cb0.png

只用了几行代码,我们就创建了一个功能完整的Rust宏!现在让 我们写个小程序测试一下:

8830ca04a1b8d27cc1e48c6c4004c2ac.png

COOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOL.


原文链接:http://blog.hubwiz.com/2020/01/30/rust-macro/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/532429.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高斯分布及其极大似然估计

高斯分布及其极大似然估计 高斯分布 一维高斯分布 一维高斯分布的概率密度函数为&#xff1a; N(μ,σ2)12πσexp⁡(−(x−μ)22σ2)N(\mu,\sigma^2)\frac{1}{\sqrt{2\pi}\sigma}\exp(-\frac{(x-\mu)^2}{2\sigma^2}) N(μ,σ2)2π​σ1​exp(−2σ2(x−μ)2​) 多维高斯分布…

农林资金 大数据审计案例_大数据审计:现状与发展

大数据审计&#xff1a;现状与发展【摘要】传统手工环境下&#xff0c;审计人员常用的审计方法包括检查法、观察法、重新计算法、外部调查法、分析法、鉴定法等。随着信息技术的发展&#xff0c;被审计单位的运行越来越依赖于信息化环境。信息化环境下审计工作发生了巨大的变化…

商标45类分类表明细表_2019版注册商标分类表,商标注册45类范围明细

注册商标的时候都是要确定具体的产品或服务的&#xff0c;目前我国商标分类是用《类似商品和服务区分表–基于尼斯分类第十一版》2019年版这本分类书。这本分类表也是全球通用的分类表&#xff0c;商标分类总共有45个类别&#xff0c;1-34类是产品类、35-45类是服务类。这45个大…

高维高斯分布基础

高维高斯分布基础 多位高斯分布的几何理解 多维高斯分布表达式为&#xff1a; p(x∣μ,Σ)1(2π)p/2∣Σ∣1/2e−12(x−μ)TΣ−1(x−μ)p(x|\mu,\Sigma)\frac{1}{(2\pi)^{p/2}|\Sigma|^{1/2}}e^{-\frac{1}{2}(x-\mu)^{T}\Sigma^{-1}(x-\mu)} p(x∣μ,Σ)(2π)p/2∣Σ∣1/21​…

angularjs sill 创建项目_开源项目——博客项目MyBlogs.Core,基于.NET 5

个人博客站项目源码&#xff0c;高性能低占用的博客系统&#xff0c;这也许是我个人目前写过的性能最高的web项目了 。目前日均处理请求数80-120w次&#xff0c;同时在线活跃用户数30-100人&#xff0c;数据量累计已达到100多万条&#xff0c;数据库Redis网站主程序同时运行在一…

怀旧服推荐配置_【怀旧服】狂暴战P4毕业装备推荐

在怀旧服开启P4阶段之后&#xff0c;狂暴战玩家的输出也得到了进一步的提升。当然&#xff0c;狂暴战想要打出足够的伤害离不开对应的装备&#xff0c;现在就给大家介绍下狂暴战P4阶段的BIS装备。散件装备狂暴战在这一阶段依旧有非常不错的散件装备&#xff0c;个人建议玩家入手…

高斯混合模型GMM及EM迭代求解算法(含代码实现)

高斯混合模型GMM及EM迭代求解算法&#xff08;含代码实现&#xff09; 高斯分布与高斯混合模型 高斯分布 高斯分布大家都很熟悉了&#xff0c;下面是一元高斯分布的概率密度函数&#xff08;Probability Density Function&#xff0c;PDF&#xff09;&#xff1a; P(x)N(μ,…

十个模块_专栏 | ABAQUS Part模块的十个小技巧

作者介绍星辰_北极星2012年开始从事Abaqus仿真相关工作&#xff0c;服务大小课题逾百项; 主要仿真领域&#xff1a;石油工程、岩土工程和金属加工工艺&#xff1b; 重点研究方向&#xff1a;ABAQUS GUI二次开发、固体力学、断裂以及损伤等。Abaqus有部件(Part)和装配体(Assembl…

深度学习时代的视频理解综述

深度学习时代的视频理解综述 本文为b站bryanyzhu老师四期视频理解相关论文解读的汇总图文笔记。 我们先精读深度学习时代视频理解领域最为重要的两篇论文&#xff1a;双流网络和 I3D。它们分别是领域内两大类方法双流&#xff08;利用光流&#xff09;网络和 3D CNN 网络的代…

typec扩展坞hdmi没反应_typec扩展坞转hdmi/vga多功能网口usb转换器苹果华为电脑matebook6元优惠券券后价26.8元...

★typec扩展坞转hdmi/vga多功能网口usb转换器苹果华为电脑matebook&#xff0c;6元拼多多优惠券★券后价26.8元★★★typec扩展坞转hdmi/vga多功能网口usb转换器苹果华为电脑matebook&#xffe5;26.8元&#xffe5;32.8元已拼5097件点击抢购猜你喜欢[速发]喵喵机P1热敏打印机手…

NLP任务概览

NLP任务概览 本文为台湾大学李宏毅老师视频课程笔记。本课程介绍了 &#xff08;2020年&#xff09;NLP 领域常见的 17 种任务。本文只会从输入输出的角度概览多种 NLP 任务&#xff0c;并简介它们的常见做法&#xff0c;并不会细致地介绍每个任务模型的具体细节。 两种模式与…

大物实验总结模板_期中总结大会amp;期末动员大会

在逐渐降温的双创周麦包坊的期中总结暨期末动员大会来啦在学长团和小麦包的分享下希望大家重新启航奋斗期末板块一学长团经验分享面对本学期十二门科目&#xff0c;作为过来人的前辈们给出很多对本学期各科目的针对性建议&#xff0c;可谓是干货满满&#xff0c;快来瞧瞧吧&…

PTMs:NLP预训练模型的全面总结

PTMs&#xff1a;NLP预训练模型的全面总结 转自&#xff1a;https://zhuanlan.zhihu.com/p/115014536 预训练模型(Pre-trained Models,PTMs) 的出现将NLP带入了一个全新时代。2020年3月18日&#xff0c;邱锡鹏老师发表了关于NLP预训练模型的综述《Pre-trained Models for Natur…

python中提取几列_Python一键提取PDF中的表格到Excel(实例50)

从PDF文件获取表格中的数据&#xff0c;也是日常办公容易涉及到的一项工作。一个一个复制吧&#xff0c;效率确实太低了。用Python从PDF文档中提取表格数据&#xff0c;并写入Excel文件&#xff0c;灰常灰常高效。上市公司的年报往往包含几百张表格&#xff0c;用它作为例子再合…

EM算法公式推导

EM算法公式推导 EM 算法是一种用来进行含有隐变量的概率生成模型参数估计的迭代算法。 EM算法步骤 EM 算法通过迭代求 L(θ)log⁡P(X∣θ)L(\theta)\log P(X|\theta)L(θ)logP(X∣θ) 的极大似然估计&#xff0c;每次迭代包含两部&#xff1a;E步&#xff0c;求期望&#xf…

详解最大似然估计(MLE)、最大后验概率估计(MAP),以及贝叶斯公式的理解

详解最大似然估计&#xff08;MLE&#xff09;、最大后验概率估计&#xff08;MAP&#xff09;&#xff0c;以及贝叶斯公式的理解 声明&#xff1a;本文为原创文章&#xff0c;发表于nebulaf91的csdn博客。欢迎转载&#xff0c;但请务必保留本信息&#xff0c;注明文章出处。 本…

elemntui icon 大小_自定义elementui中的图标

前提elementui图标库图标较少当你想用elementui的控件而不想用它的图标时&#xff0c;就可以使用自定义的方式来实现实现el-icon-my-export为我自定义的图标命名导出//使用图片来替换//before属性中的content文本是用来占位的,必须有//可以设置字体大小来确定大小//使用visibil…

变分推断公式推导

变分推断公式推导 背景介绍 机器学习中的概率模型可分为频率派和贝叶斯派。频率派最终是求一个优化问题&#xff0c;而贝叶斯派则是求一个积分问题。 频率派 举几个例子&#xff1a; 线性回归 样本数据&#xff1a;{(xi,yi)}i1N\{(x_i,y_i)\}_{i1}^N{(xi​,yi​)}i1N​ 模…

重新打开_iPhone 应用停止响应或无法打开的解决办法

如果当您在 iPhone 上使用某个重要应用时&#xff0c;遇到应用停止响应、意外退出或无法打开的问题&#xff0c;请参考如下步骤尝试解决&#xff1a;1.强制退出应用&#xff1a;在 iPhone 后台强制关闭该应用之后&#xff0c;再次重新打开看看。2.重启您的设备&#xff0c;然后…

机器学习理论——优雅的模型:变分自编码器(VAE)

机器学习理论——优雅的模型&#xff1a;变分自编码器&#xff08;VAE&#xff09; 转自&#xff1a;机器学习理论—优雅的模型&#xff08;一&#xff09;&#xff1a;变分自编码器&#xff08;VAE&#xff09; 另外直观理解 VAE&#xff0c; 推荐 台大李宏毅老师的课程&#…