当前位置: 首页 > news >正文

在线涨粉平台汉中网站seo

在线涨粉平台,汉中网站seo,服装厂做1688网站效果好不好,企业网站主题原文 Rust2018中的过程宏 在Rust2018版本中,我最喜欢的功能是过程宏.在Rust中,过程宏有着悠久而传奇的历史(并继续拥有传奇的未来!) 因为2018年版极大改善了定义和使用它们的体验. 什么是过程宏 过程宏是,在编译时用一段语法,生成新语法的函数.Rust2018中的过程宏有三个风格…

原文

Rust2018中的过程宏

Rust2018版本中,我最喜欢的功能是过程宏.在Rust中,过程宏有着悠久而传奇的历史(并继续拥有传奇的未来!)
因为2018年版极大改善了定义和使用它们的体验.

什么是过程宏

过程宏是,在编译时一段语法,生成新语法的函数.Rust2018中的过程宏有三个风格:

1,自Rust1.15以来,#[derive]模式宏一直很稳定,并把#[derive(Debug)]所有优点和易用性也带到了用户定义的特征中,如Serde#[derive(Deserialize)].
2,函数式宏,在2018版中是新的稳定版本,并允许在基于crates.io的库中定义:

env!("FOO") 
format_args!("...")

宏.类似macro_rules!宏.

3,我最喜欢的属性宏,也是2018版中的新功能,它允许在Rust函数上提供轻量注解,来编译时语法转换代码.

可在清单中用proc-macro=true指定宏.使用时,Rust编译器会加载过程宏,并在展开调用时执行它.
Cargo可控制过程宏版本,且可像其他Cargo依赖项一样轻松使用它们!

定义过程宏

这三类的定义方式略微不同,在此以属性宏为例.首先,标记Cargo.toml:

[lib]
proc-macro = true

然后在src/lib.rs中,可编写宏:

extern crate proc_macro;
use proc_macro::TokenStream;
#[proc_macro_attribute]
pub fn hello(attr: TokenStream, item: TokenStream) -> TokenStream {//...
}

然后可在tests/smoke.rs中编写单元测试:

#[my_crate::hello]
fn wrapped_function() {}
#[test]
fn works() {wrapped_function();
}

…就这样!执行cargo test的测试时,Cargo编译过程宏.之后,它编译编译时加载宏的单元测试,执行hello函数并编译生成的语法.

可见过程宏的几个重要属性:

1,输入/输出TokenStream类型
2,编译时可执行任意代码,即几乎不受限!
3,过程宏模块系统整合,即可像其他名字一样导入.

先深入了解其中的一些要点.

宏和模块系统

宏现在与Rust中的模块系统整合.表明导入宏时不再需要笨拙的#[macro_use]属性!不是:

#[macro_use]
extern crate log;
fn main() {debug!("hello, ");info!("world!");
}

你可以如下:

use log::info;
fn main() {log::debug!("hello, ");info!("world!");
}

好处不仅限于!风格的macro_rules宏,因为现在可转换如下代码:

#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)]
struct Foo {//...
}
//为
use serde::Deserialize;
#[derive(Deserialize)]
struct Foo {//...
}

甚至不需要显式依赖Cargo.toml中的serde_derive!,只需要:

[dependencies]
serde = { version = '1.0.82', features = ['derive'] }

TokenStream内部

神秘的TokenStream类型,来自编译器提供的proc_macro仓库.
首次添加TokenStream时,只能调用to_string()parse()来回来转换其为从串转换.
Rust2018开始,可直接操作TokenStream中的令牌.

TokenStream"只是"TokenTree上的一个迭代器.Rust中的所有语法都分四类,即TokenTree的四种变体:
1,Ident是如foobar的标识.它还包含如selfsuper的关键字.
2,字面(Literal)包括像1,"foo""b"等内容.所有字面都是表示程序中常量值一个令牌.
3,Punct表示标点符号,而不是分隔符.

.foo.bar字段访问中的Punct令牌.像=>多符标点符号表示为两个Punct标记,一个表示=,一个表示>,Spacing枚举表示=与>相邻.

4,Group"树"项最相关的地方,因为Group代表一个分隔子令牌流.如,(a,b)是以括号作为分隔符Group,内部令牌流a,b.

最小化TokenTree对稳定性至关重要.
稳定RustAST是不可行的,因为那表示不能改变它.(想像假如如果不能添加?符号).

TokenStream过程宏通信,在同时可编译和处理较旧过程宏时,编译器添加新的语言语法.不过,先看看如何从TokenStream中取有用的信息.

解析TokenStream

但,只需要看看syn仓库.
使用syn仓库,可用单行代码解析RustAST:

#[proc_macro_attribute]
pub fn hello(attr: TokenStream, item: TokenStream) -> TokenStream {let input = syn::parse_macro_input!(item as syn::ItemFn);let name = &input.ident;let abi = &input.abi;//...
}

syn仓库不仅可解析内置语法,且还可轻松地为自己的语法编写递归下降解析器.更多.

生成TokenStream

不仅要以TokenStream作为过程宏的输入,还要生成TokenStream作为输出.一般要求输出是有效的Rust语法,但与输入一样,它只是要构建的令牌列表.
创建TokenStream的唯一方法是通过其FromIterator实现,即必须逐个创建每个令牌并聚集它到TokenStream中.
不过,这很乏味,所以看看synquote兄弟仓库.
quote仓库是Rust的准引用实现,主要提供了一个方便的宏:

use quote::quote;
#[proc_macro_attribute]
pub fn hello(attr: TokenStream, item: TokenStream) -> TokenStream {let input = syn::parse_macro_input!(item as syn::ItemFn);let name = &input.ident;//输入函数总是等价于返回`42`,对不?let result = quote! {fn #name() -> u32 { 42 }};result.into()
}

quote!宏这里允许你编写大部分Rust语法,并用#foo环境快速插值变量.

令牌和跨度(Span)

也许Rust2018中过程宏的最大特性是可自定义和使用每个令牌上的Span信息,这样可从过程宏中取得惊人语法错误消息:

error: expected `fn`--> src/main.rs:3:14|
3 | my_annotate!(not_fn foo() {});|              ^^^^^^

完全自定义的错误消息:

 错误:`导入`方法必须至少`有一个`参数--> invalid-imports.rs:12:5|
12 |     fn f1();|     ^^^^^^^^

Span可看作是原始源文件的指针,一般表示,foo,"Ident令牌来自文件bar.rs,第4行第5列,长度为3个字节".
此信息主要由包含警告和错误消息的编译器诊断使用.

Rust2018中,每个TokenTree都有个与之关联的Span.即,如果把所有输入令牌Span保留到输出中,则即使生成全新语法,编译器的错误消息仍是准确的!
如,如下一个小宏:

#[proc_macro]
pub fn make_pub(item: TokenStream) -> TokenStream {let result = quote! {pub #item};result.into()
}

按如下调用:

my_macro::make_pub! {static X: u32 = "foo";
}

是无效的,因为从应该返回u32的函数返回一个,编译器帮助诊断问题为:

 `error[E0308]`:`类型`不匹配--> src/main.rs:1:37|
1 | my_macro::make_pub!(static X: u32 = "foo");|                                     ^^^^^ expected u32, found reference|=注意:期望类型为`"U32"`找到类型`'&'staticstr'`错误:因为上一个错误而中止

在此可见,尽管正在生成全新语法,但编译器可保留span信息,以继续为编写代码提供针对性的诊断.

生态中的过程宏

syn,quoteproc-macro2是编写过程宏首选库.方便自定义解析器,解析现有语法,创建新语法,使用旧版本Rust等等!

Serde这里及SerializeDeserialize继承宏可能是生态中最常用的宏.它们有令人印象深刻的配置量,是小注解但强大的很好示例.

wasm-bindgen项目在Rust中,使用属性宏轻松定义接口,并从JS导入接口.
#[wasm_bindgen]轻量注解方便理解传入和传出内容,并删除了大量转换样板.

gobject_gen!宏是GNOME项目的实验性IDL,来在Rust中安全地定义GObject对象,避免手写来与C语言通信,并用Rust写其他GObject实例交互期望的所有胶水.

Rocket框架最近切换到了过程宏,并展示了过程宏的一些最新功能,如自定义诊断,自定义跨度创建等.

http://www.tj-hxxt.cn/news/47070.html

相关文章:

  • 微网站开发的比较总结百度客服怎么联系
  • 如何做自己的淘宝优惠券网站最新社会舆情信息
  • 深圳外贸网站优化哪家好seo sem是什么职位
  • 微信房地产网站建设创建网站的公司
  • 网站建设安全规划学做网站培训班要多少钱
  • 排名好的青岛网站建设优化公司排行榜
  • 网页设计实训报告前言潍坊seo培训
  • 网站空间支持下载但不能下载文件360优化大师app下载
  • 深圳网站建设怎么办windows永久禁止更新
  • 张家港快速网站建设网上接单平台
  • 中国空间站朋友圈描述优化方法
  • 软件界面设计app聊城seo整站优化报价
  • 网站问卷调查怎么做什么时候网络推广
  • 有哪些网站能够免费找到素材自己怎么做网站优化
  • 丰台新乡网站建设如何免费建立一个网站
  • 做网站买哪家的主机好网站推广优化排名教程
  • 做封面字体下载好的网站个人网站制作多少钱
  • wordpress新版编辑四川二级站seo整站优化排名
  • 网站被做跳转怎么办百度纯净版首页入口
  • 自己怎么搞个软件出来北京网络推广公司wyhseo
  • 西藏建设网站seo如何优化网站步骤
  • 做外贸建网站2021年网络热点舆论
  • 杭州网站建设教育机构怎么进行seo
  • 电子商务网站建设程序应用题徐州网站建设
  • 城乡建设部网站首页上海搜索引擎技术包括哪些
  • 代理记账网站模板抖音账号权重查询
  • 代做毕业设计网站家具设计seo关键词排名优化的方法
  • 拖拽式wordpress建站搜索引擎网站优化推广
  • 物流企业网站晋中网络推广
  • 网站中的横幅怎么做优化推广网站seo