陈天 · Rust 编程第一课
陈天
Tubi TV 研发副总裁
23195 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 65 讲
基础篇 (21讲)
陈天 · Rust 编程第一课
15
15
1.0x
00:00/00:00
登录|注册

20|4 Steps :如何更好地阅读Rust源码?

研究 BytesMut 的 split_off() 方法
BufMut trait 的文档
Buf trait 的实现
分析 Bytes 的 clone()
深入研究实现逻辑
掌握主要的 struct
熟悉核心 trait 的行为
从大纲开始
打破天花板
学习技巧
知识的源头
打破天花板
学习技巧和思路
理解系统的行为
参考资料
思考题
如何阅读源码呢?
三大功用
为什么要阅读源码?
阅读源码

该思维导图由 AI 生成,仅供参考

你好,我是陈天。
到目前为止,Rust 的基础知识我们就学得差不多了。这倒不是说已经像用筛子一样,把基础知识仔细筛了一遍,毕竟我只能给你提供学习 Rust 的思路,扫清入门障碍。老话说得好,师傅领进门修行靠个人,在 Rust 世界里打怪升级,还要靠你自己去探索、去努力。
虽然不能帮你打怪,但是打怪的基本技巧可以聊一聊。所以在开始阶段实操引入大量新第三方库之前,我们非常有必要先聊一下这个很重要的技巧:如何更好地阅读源码
其实会读源码是个终生受益的开发技能,却往往被忽略。在我读过的绝大多数的编程书籍里,很少有讲如何阅读代码的,就像世间的书籍千千万万,“如何阅读一本书”这样的题材却凤毛麟角。
当然,在解决“如何”之前,我们要先搞明白“为什么”。

为什么要阅读源码?

如果课程的每一讲你都认真看过,会发现时刻都在引用标准库的源码,让我们在阅读的时候,不光学基础知识,还能围绕它的第一手资料也就是源代码展开讨论。
如果说他人总结的知识是果实,那源代码就是结出这果实的种子。只摘果子吃,就是等他人赏饭,非常被动,也不容易分清果子的好坏;如果靠朴素的源码种子结出了自己的果实,确实前期要耐得住寂寞施肥浇水,但收割的时刻,一切尽在自己的掌控之中。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了如何更好地阅读 Rust 源码以及阅读源码的三大功用。作者以第三方库 Bytes 为例,详细讲解了如何从大纲开始、深入阅读代码。通过阅读源码,读者可以更好地理解代码的功能和使用方式,学习到技巧,积累素材,开拓思路,最终形成自己的智慧。文章提供了很好的指导和方法论,对于想要提高阅读 Rust 源码能力的读者来说,具有很高的参考价值。文章内容包括了阅读源码的四个步骤,以及如何熟悉核心 trait 的行为和掌握主要的 struct。通过深入阅读源码,读者可以学习到高手定义 trait 的思路,了解数据结构的内部结构和设计,以及如何实现需要的标准 trait。这篇文章对于 Rust 开发者来说,是一份非常有用的指南,可以帮助他们更好地理解和应用 Rust 源码。文章还提供了一些思考题,帮助读者更深入地理解所学内容。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《陈天 · Rust 编程第一课》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(18)

  • 最新
  • 精选
  • Geek_1b6d74
    陈天大神太强了,学习他的课程不仅学习了一门新的语言,还弄明白了很多编程底层原理

    作者回复: 过奖了!:)

    2021-10-13
    15
  • 核桃
    老师,专门开一期如何读开源项目源码吧,真的,这个比懂任何技巧都更有意义,目前也没有教这个的。

    作者回复: :) 掌握好这一章就好了啊

    2021-11-20
    6
  • 枸杞红茶
    我原本准备去超市摸鱼,陈天老师给我渔船把我扔到了大海里

    作者回复: 哈哈,放下你泡好枸杞红茶的保温杯,一起死磕 Rust :)

    2021-10-31
    5
  • Marvichov
    1. 我们一起大致分析了 Bytes 的 clone() 的使用的场景,你能用类似的方式研究一下 drop() 是怎么工作的么? 如果是Shared, 就像Arc那样decrease counter; 如果是KIND_VEC, with unique ownership, deallocate memory immediately. unsafe fn promotable_odd_drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize) { data.with_mut(|shared| { let shared = *shared; let kind = shared as usize & KIND_MASK; if kind == KIND_ARC { release_shared(shared as *mut Shared); } else { debug_assert_eq!(kind, KIND_VEC); drop(rebuild_boxed_slice(shared as *mut u8, ptr, len)); } }); } 2. 仔细看 Buf trait 里的方法,想想为什么它为 &mut T 实现了 Buf trait,但没有为 &T 实现 Buf trait 呢?如果你认为你找到了答案,再想想为什么它可以为 &[u8] 实现 Buf trait 呢? 因为advance method需要更改T内部状态 fn advance(&mut self, cnt: usize) { 3. 花点时间看看 BufMut trait 的文档。Vec 可以使用 BufMut 么?如果可以,试着写写代码在 Vec 上调用 BufMut 的各种接口,感受一下。 只能在`Vec<u8>` 上用; 跟着doc试了一下. 值得注意的是, `advance_mut`是 `unsafe`: #[inline] unsafe fn advance_mut(&mut self, cnt: usize) { let len = self.len(); let remaining = self.capacity() - len; assert!( cnt <= remaining, "cannot advance past `remaining_mut`: {:?} <= {:?}", cnt, remaining ); self.set_len(len + cnt); } 4. 如果有余力,可以研究一下 BytesMut。重点看一下 split_off() 方法是如何实现的。 `split_off` 也是根据kind来: - 如果是KIND_VEC, 就变成两个Arc, 共享同一个buf pointer - 如果是KIND_ARC, 就increase ref count, 设置不同的start, end 感觉真正困难的是 `reserve` 和 `resize`; 这两个method要求KIND_ARC; 这样, 所有outgoing的`BytesMut` 能view underlying Vec pointer change during reallocation

    作者回复: 👍

    2021-11-08
    2
  • Geek2014
    而 data 这个 AtomicPtr 指针,在指向 Shared 结构时,这个结构的对齐是 2/4/8 字节(16/32/64 位 CPU 下),末尾一定不为 0: 老师,为啥对齐2/4/8字节,末尾一定不为0呢

    作者回复: 啊,多谢发现!这里是笔误,应该是一定为 0。为 0 才可以借用最后一位设置是否是 shared 标志。这是上下文的逻辑。我让编辑更新一下。

    2021-10-08
    2
  • Geek_b52974
    看後面的解釋還是有點懵,我試著照自己的理解說明 最後一位是用來記錄是否是 shared 但是我們會需要知道升級成 shared 前最後一位是 odd 還是 event 所以用 PROMOTABLE_ODD_VTABLE PROMOTABLE_EVENT_VTABLE 來做不同的 clone 方式 ``` unsafe fn promotable_even_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes { let shared = data.load(Ordering::Acquire); let kind = shared as usize & KIND_MASK; if kind == KIND_ARC { shallow_clone_arc(shared as _, ptr, len) } else { debug_assert_eq!(kind, KIND_VEC); let buf = (shared as usize & !KIND_MASK) as *mut u8; shallow_clone_vec(data, shared, buf, ptr, len) } } ``` promotable_event_clone 相比 promotable_odd_clone 多了下面這個操作 let buf = (shared as usize & !KIND_MASK) as *mut u8; 先把最後一位還原成原本的樣子,再進行 clone 不知道這樣理解對不對

    作者回复: 对

    2021-11-05
    1
  • 25ma
    值得反复深度阅读,很有收获

    编辑回复: 👍

    2022-07-08
  • 施泰博
    看完我觉得值得,得反复看很多编了。

    作者回复: 👍

    2021-12-18
  • overheat
    Bytes可以支持反序吗?我想要从结尾往开头操作。。。

    作者回复: 不支持,你需要先做 reverse 的操作

    2021-12-10
    3
  • 小康
    老师,目前中国rust岗位很多都是区块链相关的技术岗位呀???java转Rust跨度会不会太大???

    作者回复: 1. 目前是,以后基础软件会有越来越多的 Rust 职位 2. 不会

    2021-11-13
收起评论
显示
设置
留言
18
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部