Giter Site home page Giter Site logo

warrenren / inside-rust-std-library Goto Github PK

View Code? Open in Web Editor NEW
1.4K 32.0 188.0 791 KB

本书已经正式出版,目前正预售,可在京东搜索《深入RUST标准库》即可。本书主要对RUST的标准库代码进行分析,并试图给出RUST标准库代码的分析脉络。This project try to give a venation of how reading the RUST standard library source code.

License: GNU General Public License v2.0

inside-rust-std-library's Introduction

inside-rust-std-library

实体书已经出版,名字为《深入rust标准库》,正在预售,可在京东搜索到。欢迎大家采购实体书籍,给作者一些支持。
本书主要对RUST的标准库代码进行分析。
本书尽可能给读者找出一条标准库代码的阅读脉络。同时,分析不仅仅针对代码的功能,也针对代码背后的需求及若干代码设计的思路。
C语言精通的标志是对指针的精通。RUST的裸指针也是RUST的最基础及最核心的难点之一。 所以,将裸指针及相关的内存模块作为代码分析的起始点,熟悉了裸指针及内存,自然也就对所有权,借用,生命周期的本质有了深刻的理解,RUST语言的最难关便过了。
泛型是RUST不可分割的语法之一,而对于其他语言,没有泛型不影响语言的使用。泛型及基于trait的泛型约束是RUST的另一个代码基础。
针对基本类型的分析,可以看到RUST利用trait语法使之具备了无限的扩展性,这是RUST更有表现力的语法能力的展现。
Option/Result<T,E>等类型实际完全是由标准库定义的,并不是RUST语言最底层的基本内容,可以从代码分析中发现这一点。
所有的运算符都可以重载,且可以跨越类型重载,RUST的运算符重载揭示了RUST很多的编码奥秘及技巧。
Iterator加闭包是函数式编程的基础构架,Iterator的适配器构成了函数式编程的基础设施,RUST完整的实现了这些内容,并且几乎为每个类型都实现了迭代器,并尽可能的为函数式编程做好了准备。
Cell/RefCell/Pin/Lazy代码证明了在RUST的基础语法下,如何创造性的解决问题。
Box/RawVec是两个堆内存申请的基本结构,善用这两个结构,除非写内存管理,基本上就不必再接触底层的堆内存申请及释放。
每一个智能指针实际上也是RUST对经典的数据结构实现的精妙例程。
RUST对不同操作系统的适配让程序员不必象C那样再重复的耗费精力并且还沾沾自喜于此份工作。
仅支持异步编程的async/await,Future也体现了RUST的作最基础的工作的态度。
...
...

(This book focuses on the analysis of RUST's standard library code.
This book is as far as possible to find a reading context for the standard library code. At the same time, the analysis is not only for the function of the code, but also for the requirements behind the code and some ideas of code design.
The hallmark of C proficiency is mastery of pointer. The raw pointer in RUST is also one of the most basic and core difficulties of RUST. Therefor, the raw pointer and associated memory modules are used as the starting point for code analysis, and the familiarity with raw pointer and memory naturally leads to a profound understanding of the nature of ownership, borrowing, and the life cycle. The hardest part of RUST is over.
Generics are an integral part of RUST's syntax, and for other languages, the absence of generics does not affect language use. Generics and their trait - based generic constraints are another code base of RUST.
Based on the analysis of primitive types, it can be seen that RUST makes use of trait syntax to make primitive types infinitely extensible, which is a demonstration of RUST's more expressive syntax ability.
Types such as Option/Result<T, E> are actually defined entirely by the standard library and are not the basic content of the lowest level of the RUST language, as you can see from code analysis.
All operators can be overloaded and can cross type overloading. Operator overloading in RUST reveals many of RUST's coding secrets and tricks.
Iterator plus closures are the foundation of functional programming. The adapters of Iterator make up the infrastructure of functional programming. RUST implements them completely, implementing iterators for almost every type and preparing them as well as possible for functional programming.
The Cell/RefCell/Pin/Lazy source code demonstrates how creative problem solving can be done within RUST's basic syntax.
Box/RawVec are the two basic structures of heap memory allocation and freeing.
Each smart pointer is actually an elegant routine of RUST's implementation of classical data structures.
RUST's adaptation of different operating systems saves programmers from the repetitive effort and complacency of C.
Supporting only async/await for asynchronous programming, Future also embodies RUST's attitude of doing the most basic work.
... ... )

inside-rust-std-library's People

Contributors

warrenren avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

inside-rust-std-library's Issues

内容出现重复,可能是写错误的

在第二章的内存部分

裸指针偏移计算相关方法
ptr::const T::offset(self, count:isize)-> const T 得到偏移后的裸指针
ptr::*const T::wrapping_offset(self, count: isize) -> *const T 考虑溢出绕回的offset
ptr::*const T::offset_from(self, origin: *const T) -> isize 计算两个裸指针的offset值
ptr::mut T::offset(self, count:isize)-> mut T 偏移后的裸指针
ptr::*const T::wrapping_offset(self, count: isize) -> *const T 考虑溢出绕回的offset
ptr::*const T::offset_from(self, origin: *const T) -> isize 计算两个裸指针的offset值
以上两个方法基本上通过intrinsic的函数实现

最后的两个函数和前面的重复了ptr::*const T::offset_from(self, origin: *const T) -> isize 比如这个就出现了两次。
还有在最新的rust版本里面有些函数已经不存在了。该仓库应该注明该文章有效的rust版本号

关于章节`裸指针小结`的示例代码的疑问

我本地使用rustc 1.60.0试了一下,发现这一段代码是可以编译运行的,Playground

章节位置

示例代码:

#[repr(packed)]
struct RefTest {a:u8, b:u16, c:u32}
fn main() {
   let test = RefTest{a:1, b:2, c:3};
   //下面代码无法通过编译,因为test.b 内存字节位于奇数,无法用于借用
   let ref1 = &test.b
}

关于对内部可变性类型的理解

07-内部可变性类型 一节中提到:

内部可变性的基础是Borrow trait

首先 Borrow trait 的用途和内部可变性并没有直接关联,这个 trait 提供的功能更像是一个类型转换。就像文档的 Example 章节提到的,一个典型例子是 HashMap::get 函数让内部存储的值类型和传入的借用类型产生关联。RefCell::borrow 函数虽然和 Borrow::borrow 命名有些类似,但仔细观察可以发现 RefCell::borrowRefCell 本身的实现,而不是 Borrow trait 的实现。

UnsafeCell逃脱RUST对引用安全检查的方法实际上就是个通常的unsafe 的裸指针操作,没有任何神秘性可言。

UnsafeCell 以外的任何类型,从 & 得到内部的 &mut 都是 undefined behavior,无论是通过指针转换还是 std::mem::transmute 等方法。UnsafeCell 可以绕过 borrow rules 的假设是因为编译器对它有特殊处理(即开洞),这也是为什么 UnsafeCell 是一个 lang term,见 https://doc.rust-lang.org/src/core/cell.rs.html#1837 。如果用户尝试复刻一个 UnsafeCell,最终也会产生 unsoundness。

关于对 `Iterator` 理解的讨论

05-Iterator 一章中提到:

Iterator在函数式编程中是居于最核心的地位。

但事实上 Iterator 的接口设计加上整个 Rust 的计算模型和函数式范式相去甚远。这个灵魂函数 Iterator::next 的第一个参数是 &mut self,实际上在鼓励实现者使用可变的内部状态来进行迭代,事实上很多实现结构也是如此。而函数式的一大特性就是不可变性,这样改变内部状态的做法并不 idiomatic。

内存章节关于dangling指针的探讨

创建一个悬垂(dangling)指针, 保证指针满足类型内存对齐要求。该指针可能指向一个正常的变量,所以不能认为指向的内存是未初始化的。dangling实际表示`NonNull<T>`无意义,与`NonNull<T>`的本意有些违背,因为这个语义可以用None来实现。
```rust
pub const fn dangling() -> Self {
unsafe {
//取内存对齐地址作为裸指针的地址。
//调用者应保证不对此内存地址进行读写
let ptr = mem::align_of::<T>() as *mut T;
NonNull::new_unchecked(ptr)
}
}
```

该指针可能指向一个正常的变量,所以不能认为指向的内存是未初始化的。

这个dangling函数就是把指定类型的对齐值作为一个usize,再把这个usize用std::mem::transmute转为一个指针,所以是不是不能认为它指向一个可能的变量,因为这个指针的值本身还没有完成初始化。 所以在这个基础上,去说它指向的内存是否初始化,没有意义。

dangling实际表示NonNull<T>无意义,与NonNull<T>的本意有些违背,因为这个语义可以用None来实现。

既然dangling返回一个NonNull,那么这个指针绝对不是==0的

  1. 它返回的是对齐值,任何类型,即使size=0,align也不会等于0。
  2. Option<NonNull>大小是T,编译器不会为Some是NonNull的option分配额外的内存填充去当索引,因为如果这个option=0,就代表它是None。所以不可以用None实现,否则会导致UB。

比如:

    let ptr = unsafe { NonNull::<u32>::new_unchecked(std::ptr::null_mut()) };
    let op = Some(ptr);
    assert_eq!(op.is_none(), true);

关于章节 `内存` 的疑问

在第二章 RUST标准库内存模块代码分析 裸指针标准库代码分析 里的 1、2 点:

  1. 将 usize 类型数值强制转换成裸指针类型,以此数值为首地址的内存块被转换为相应的类型。这一转换是不安全的。
  2. 在不同的裸指针类型之间进行强制转换,实质上完成了裸指针指向的内存块的类型强转,这一转换是不安全的。

这里提到的 不安全 是指这两个操作是 unsafe 的意思吗?
如果是的话,这个表述是有误的。例如:

#![allow(unused)]

struct Foo {
    a: i32,
    b: i64,
    c: u8,
}

struct Bar {
    a: i64,
    b: u64,
}

fn main() {
   let foo_ptr = 0usize  as *const Foo;
   let bar_ptr = foo_ptr as *const Bar;
}

这段代码是可以通过编译的。换句话说,1、2 点提到的操作都是 safe 的。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.