《Rust 设计模式》阅读笔记

date
Mar 21, 2022
slug
notes-of-rust-patterns
status
Published
tags
summary
本文是针对书中相关内容的发散,并非总结,建议读完书后再看本文。
type
Post
本文是针对书中相关内容的发散,并非总结,建议读完书后再看本文。

借用类型当做参数背后的原理

Rust 在函数参数部分有个语法糖特性,会帮助我们自动解引用,一直解到符合函数签名为止。
fn hello(word: &str) {}

let word: String = "world".to_string();

hello(&word);
为什么在函数参数声明为 &str 的情况下,传入 &String 不会报错?
因为, hello(&word); 其实会被 Rust 转换成

hello(word.deref());
同时, Rust 在标准库里为 String 做了如下实现
impl Deref for String {
  type Target = str;
	fn deref(&self) -> &Self::Target {
    // ...
  }
}
所以, &String 就被解引用成了 &str ,符合了调用函数的签名。
Rust 语言中文社区有篇文章讲的更准确点: `Deref coercion`(自动解引用类型转换)精制总结

format! 不是拼接字符串的最佳实践

format! 的性能问题
0 ns/iter (+/- 0)         from_bytes
10 ns/iter (+/- 0)        concat_string_macro
10 ns/iter (+/- 0)        concat_strs_macro
10 ns/iter (+/- 0)        mut_string_with_capacity_push_str_char
10 ns/iter (+/- 0)        string_concat_macro
10 ns/iter (+/- 1)        mut_string_with_capacity_push_str
14 ns/iter (+/- 0)        concat_in_place_macro
19 ns/iter (+/- 10)       mut_string_with_too_much_capacity_push_str
22 ns/iter (+/- 0)        array_join
24 ns/iter (+/- 0)        array_concat
24 ns/iter (+/- 0)        array_join_long
24 ns/iter (+/- 0)        mut_string_push_str
27 ns/iter (+/- 0)        string_from_plus_op
27 ns/iter (+/- 0)        to_string_plus_op
29 ns/iter (+/- 0)        to_owned_plus_op
30 ns/iter (+/- 0)        collect_from_array_to_string
34 ns/iter (+/- 0)        collect_from_vec_to_string
39 ns/iter (+/- 0)        mut_string_with_too_little_capacity_push_str
43 ns/iter (+/- 1)        string_from_all
46 ns/iter (+/- 0)        joinery
52 ns/iter (+/- 0)        format_macro
53 ns/iter (+/- 0)        format_macro_implicit_args
68 ns/iter (+/- 1)        mut_string_push_string

Visitor 模式的痛点

Visitor 模式常用于实现 AST 的遍历,但由于 Rust 的所有权特性和强类型,使得 Rust 的 Visitor 的功能是受限的。在 GC 语言的 Visitor 模式中,当遍历到某一节点时,你能够访问此节点及其父节点,但是在 Rust 中就只能访问到此节点,感知不到父节点。
我们可以看下 SWC 的 trait 签名来感受下
TOOD
不过实践中的场景都可以用各种方法绕过去,但开发体验着实是差了很多。 rslint 有篇 文章 深入浅出的介绍了这个问题和 Rust 方式的解决方案。
如果肯接受性能上的损失的话, 你可以通过使用 Rowan 来构建特殊内存结构的 AST 来获得与 GC 语言差不多的体验。
这有一些与 rowan 相关的项目
  • rslint 基于 rowan 构建的 JavaScript 的 Parser

感受

本书是一本小巧的书,肯花时间的话,一天就读完了。书里的知识有点深潜不一,也没有知其然,知其所以然的解析,从心情上来讲还是有点失望的。
读完本书的收获的话
  • 更多是一些琐碎知识点的了解
  • 还有部分设计模式的 Rust 实现以及应用
总的来讲,还是推荐一看的
本书的 Issue 区里面有很多其他设计模式的讨论,相关一些链接到另一个 Github 仓库 rust-design-pattern 。两个仓库似乎有意愿进行合并,不过这都是题外话了。

© 何云飞 2021 - 2024