-
第四章用了一个行星通信的例子来阐述整个主题,主要角色有地面站(Ground station)、人造卫星(CubeSat),两者有不同的状态并且能互相发消息通信;
-
Rust有类型安全(type safety)机制来检查函数的类型和返回值,如果一个自定义类型(用struct声明的)包含了非内置类型(如i32,bool等,它们实现了copy特征),在函数中作为参数时会触发移动(move)语义,其所有权被移动到函数的形参中,图4.2给了一个很直观的所有权转移的过程;
-
代码4.5和4.6给出了具备复制语义(copy semantics)的内置类型和具备移动语义(move semantics)的一般类型的使用区别,一个能够通过编译而一个不行,主要区别就在与是否实现了copy trait;
-
所有者(owner)拥有某些值的所有权(onwership),一旦owner的生命周期到了(例如走到了所在的代码块的最后}处或者其他原因),他们的析构函数(destructor)就会调用,析构函数会删除所有与之相关的引用(references)并释放内存,大部分的析构函数都会隐式调用,由编译器来完成,如果需要自己定制析构函数的实现和调用时机,可以通过Drop特征来实现,这个只在出现了通过unsafe块实现的内存分配中需要用到;
-
所有权的转移有两种途径,一种是变量绑定(variable binding),即通过
let
关键字来绑定一个对象到某个变量上;一种是通过函数,可以是函数的参数也可以是返回值,详见page115; -
解决所有权问题有4个好用的习惯,a. 如果完整的所有权不是必须的时候可以使用引用(references)详见4.5.1小节;b. 对于有Copy 特征的值可以直接复制,详见4.5.2小节;c. 重构代码,尽量减少那种生命周期很长(long-lived)的对象,详见4.5.3小节;d. 把数据打包在一个新的结构中来辅助解决移动语义的问题,详见4.5.4小节;
-
Clone
和Copy
的区别在下表4.2中做了详细的对比; -
什么情况下不用Copy,有三个原因,a. Copy的前提是仅仅引入微小的性能代价,即只有数据很小的时候(例如数字i32, i64等)使用Copy带来的性能损失微乎其微;b. Copy是bit级别的复制,可能对引用的处理不一定准确;c. 有些类型重载了Clone,它的复制与原生的复制有一些区别,例如带有引用计数的
std::rc::Rc<T>
类型; -
通过
Rc<RefCell<T>>
可以实现内部可变性,同时引入了一点运行时的开销;当使用Clone的代价过于大时,可以使用Rc<RefCell<T>>
作为一个备选,Rc<RefCell<T>>
并不是多线程安全的;详见page132;