Yukang's Page

Rust 的 dbg! 宏

前几天在群里看到有人讨论 dbg! 宏已经在 Nightly 可以使用了,最近发布的 stable 版本 1.32.0 也可以使用了。 翻看了一下并玩了玩,这个简单的宏确实是调试好帮手,特别是适合我这样的喜欢打印调试的开发者。这个提议从 2017 年 10 月开始,从 https://github.com/rust-lang/rfcs/pull/2173 可以看到,为了增加这个宏很多贡献者经过了无数次的讨论和回复。真是太佩服 Rust Team 的开发者,付出了这么多时间来增加这个看似很小又实用的功能。

使用

先看看这个调试宏是怎么使用的,目前使用这个宏需要切换到 Nightly 版本或者最新的稳定版,已经安装了 rustup 的话就很简单了:

rustup default nightly
rustup update

然后很简单就是把一个表达式当作参数传入:

fn factorial(n: u32) -> u32 {
if dbg!(n <= 1) {
dbg!(1)
} else {
dbg!(n * factorial(n - 1))
}
}
fn main() {
dbg!(factorial(5));
}

运行结果如下:

[src/main.rs:4] n <= 1 = false
[src/main.rs:4] n <= 1 = false
[src/main.rs:4] n <= 1 = false
[src/main.rs:4] n <= 1 = false
[src/main.rs:4] n <= 1 = true
[src/main.rs:5] 1 = 1
[src/main.rs:7] n * factorial(n - 1) = 2
[src/main.rs:7] n * factorial(n - 1) = 6
[src/main.rs:7] n * factorial(n - 1) = 24
[src/main.rs:7] n * factorial(n - 1) = 120
[src/main.rs:12] factorial(5) = 120

实现

原理当然也就是把表达式和位置打印出来,但是这里有个技巧,在宏里面使用 match,这是为了避免参数被调用多次,因为宏在编译之前会被展开。Rust 的宏比较复杂,也不可避免会有些 hacky,对于喜欢爱折腾的程序员还是有吸引力。再看看这个宏是怎么实现的,代码很少。:

macro_rules! dbg {
($val:expr) => {
match $val {
tmp => {
eprintln!("[{}:{}] {} = {:#?}",
file!(), line!(), stringify!($val), &tmp);
tmp
}
}
}
}

可以看到目前这个实现是只支持一个参数的,如果传入的参数类型没有实现 Copy Trait,可以传入引用。另外如果想同时打印多个参数,可以使用类似这样的做法:

dbg!((exp1, exp2))
发表评论

《见识》阅读笔记

到年底小组内还有多余的预算,于是大家都在网上选书。看到吴军出了两本新书,出于对作者的信任就直接下单了。上个周末就花了些时间很快地看完了两本。内容稍微有些重合,主要是有的例子会拿来阐述多个道理。所以两本连着看会有些作者凑书的感受。当然两本都还是不错的,读完《态度》对于我这个新手爸爸来说也是 .....
阅读全文

使用 Markown 编辑公众号方法

技术人员很多都喜欢使用 Markdown 格式来编辑文档,但是公众号后台默认不支持。 所以关于工具和流程,最近我摸索出来目前最适合自己的一套是: 还是维护之前 Hexo 那套,像代码那样使用 Git 管理,内容会上传到 Github 上。 继续使用 Typora 编辑 Markdown .....
阅读全文

开始写公众号

2018 过得很快,对于自己来说有点颓废、也很辛苦。说是颓废因为花了一些时间在游戏上,还有不少焦虑。最近看书,翻到胡适 1932 年一篇《寄语即将毕业的大学生》中写到,人到社会容易丢掉求知的欲望、抛弃学生时代的理想追求,为了防止堕落文中给出三点建议。读来觉得颇有道理,这三点建议放在现在也 .....
阅读全文

使用 peco 飞起 zsh

pecopeco 是一个能做交互式 filte 的工具,是 percol 的 Go 实现。特别适合在 shell 里做一些过滤操作,当然适合做日志方面的过滤。典型的使用方法是: zsh 配置下面这个配置主要增强了 zsh 的 history 补全,以及pwdf可以用来迅速找一个文件,并 .....
阅读全文

编译脚本到二进制

缘由因为自己习惯使用 expect 脚本登录各种服务器,有一段时间因为要登录的服务器太多了,所以之前写过一个程序来管理各种 expect 脚本。实现思路是根据配置文件,用一个程序来动态生成脚本,执行完之后再删除。这样临时生成的文件里也是包含密码等信息的。最近突然想是不是可以直接写一个程序 .....
阅读全文

SQL Injection attack

注入原理SQL注入一直是 Web 应用的一大安全隐患,注入的基本原理是通过修改输入的参数来操作后台执行的 SQL,注入可能会导致数据库被恶意修改、数据被恶意读取等严重行为。所以如果一个参数有漏洞,通过小心的构造注入点即可利用,这里的渗透攻防Web篇-SQL注入攻击初级有一些编写注入点的教 .....
阅读全文

Kong集群Left Cluster Node问题

问题Kong在实践中会有一些疑惑的地方,这里记录一下。注意这里记录的Kong集群部署的问题是0.10.3版本的,最新Kong版本已经不是通过serf来管理不同节点之间的配置同步问题。 在Kong多节点部署的时候,有时候某个节点停掉后,我们在后台可以看到left的信息,而且这个left信息 .....
阅读全文

Docker compose初始化失败问题

问题今天在Docker Postgresql用户名和密码授权的问题上花了一些时间,问题是: psql: FATAL: password authentication failed for user "postgres" admin的用户名和密码是可以在docker-compose.y .....
阅读全文

使用overcommit生成git hooks

git hooks很方便地可以在git操作流程的各个阶段加入hooks,比如执行一些脚本来检查代码风格、跑单元测试、做代码静态检查等。git hooks的试用方法是在.git/hooks目录下写各种脚本,但是.git目录的这些脚本是不会checkin到repo里的,所以如果一个代码如果被 .....
阅读全文
Prev Next