本書github鏈接:inside-rust-std-library
前面章節(jié)參見:
深入RUST標(biāo)準(zhǔn)庫內(nèi)核(序言) - 簡書 (jianshu.com)
深入RUST標(biāo)準(zhǔn)庫內(nèi)核(一 概述) - 簡書 (jianshu.com)
深入RUST標(biāo)準(zhǔn)庫內(nèi)核(二 內(nèi)存)—Layout/原生指針 - 簡書 (jianshu.com)
深入RUST標(biāo)準(zhǔn)庫內(nèi)核(二 內(nèi)存)—NonNull<T>/申請(qǐng)及釋放 - 簡書 (jianshu.com)
深入RUST標(biāo)準(zhǔn)庫內(nèi)核(二 內(nèi)存)—mem模塊/MaybeUninit<T> - 簡書 (jianshu.com)
RUST的固有(intrinsic)函數(shù)庫
intrinsic庫函數(shù)是指由編譯器內(nèi)置實(shí)現(xiàn)的函數(shù),一般如下特點(diǎn)的函數(shù)用固有函數(shù):
- 與CPU架構(gòu)相關(guān)性很大,必須利用匯編實(shí)現(xiàn)或者利用匯編才能具備最高性能的函數(shù),
- 和編譯器密切相關(guān)的函數(shù),由編譯器來實(shí)現(xiàn)最為合適。
上面內(nèi)存庫章節(jié)中已經(jīng)介紹了內(nèi)存部分的intrinsic庫函數(shù),本節(jié)對(duì)其他部分做簡略介紹
intrinsic 原子操作函數(shù)
原子操作函數(shù)主要用于多核CPU,多線程CPU時(shí)對(duì)數(shù)據(jù)的原子操作。intrinsic庫中atomic_xxx及atomic_xxx_xxx類型的函數(shù)即為原子操作函數(shù)。原子操作函數(shù)主要用于并發(fā)編程中做臨界保護(hù),并且是其他臨界保護(hù)機(jī)制的基礎(chǔ),如Mutex,RWlock等。
數(shù)學(xué)函數(shù)及位操作函數(shù)
各種整數(shù)及浮點(diǎn)的數(shù)學(xué)函數(shù)實(shí)現(xiàn)。這一部分放在intrinsic主要是因?yàn)楝F(xiàn)代CPU對(duì)浮點(diǎn)計(jì)算由很多支持,這些數(shù)學(xué)函數(shù)由匯編語言來實(shí)現(xiàn)更具備效率,那就有必要由編譯器來內(nèi)置實(shí)現(xiàn)。
intrinsic 指令優(yōu)化及調(diào)試函數(shù)
斷言類: assert_xxxx 類型的函數(shù)
函數(shù)棧:caller_location
小結(jié)
intrinsic函數(shù)庫是從編譯器層面完成跨CPU架構(gòu)的一個(gè)手段,intrinsic通常被上層的庫所封裝。但在操作系統(tǒng)編程和框架編程時(shí),仍然會(huì)不可避免的需要接觸。
RUST標(biāo)準(zhǔn)庫的基礎(chǔ)Trait
RUST中直接針對(duì)泛型實(shí)現(xiàn)方法定義和Trait
實(shí)現(xiàn)方法或Trait時(shí),可以針對(duì)泛型來實(shí)現(xiàn)特定的方法和Trait,并可以給泛型添加限制以描述??梢蕴砑拥姆盒拖拗朴校簾o限制,泛型的原生指針(可變/不可變)類型,泛型的引用(可變/不可變)類型,泛型的數(shù)組類型,泛型的切片類型,泛型的切片引用(可變/不可變)類型,泛型的元組(可變/不可變)類型,函數(shù)類型, 需實(shí)現(xiàn)特定的Trait限制等。
對(duì)某個(gè)具有針對(duì)泛型的類型結(jié)構(gòu)體實(shí)現(xiàn)方法和Trait時(shí),也可以對(duì)類型結(jié)構(gòu)體的泛型做出如上所述的限制。
舉例說明:
//為所有的類型實(shí)現(xiàn)了Borrow<T> Trait
impl<T: ?Sized> Borrow<T> for T {
fn borrow(&self) -> &T {
self
}
}
//為所有的引用類型實(shí)現(xiàn)Receiver Trait
impl<T: ?Sized> Receiver for &T {}
//為所有可變引用類型實(shí)現(xiàn)Receiver Trait
impl<T: ?Sized> Receiver for &mut T {}
//為所有原生不可變指針類型實(shí)現(xiàn)Clone Trait
impl<T: ?Sized> Clone for *const T {
fn clone(&self) -> Self {
*self
}
}
//為原生可變指針類型實(shí)現(xiàn)Clone Trait
impl<T: ?Sized> Clone for *mut T {
fn clone(&self) -> Self {
*self
}
}
//為切片類型[T]實(shí)現(xiàn)AsRef<[T]> Trait
impl<T> AsRef<[T]> for [T] {
fn as_ref(&self) -> &[T] {
self
}
}
// 切片的方法 具體實(shí)現(xiàn)的摘要
// [T;N]代表數(shù)組類型,[T]代表切片類型,
// 下面是針對(duì)所有切片類型的統(tǒng)一方法。
impl<T> [T] {
pub const fn len(&self) -> usize {
unsafe { crate::ptr::PtrRepr { const_ptr: self }.components.metadata }
}
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
//以下代碼展示了RUST代碼的極簡潔及易理解
pub const fn first(&self) -> Option<&T> {
if let [first, ..] = self { Some(first) } else { None }
}
pub const fn split_first(&self) -> Option<(&T, &[T])> {
if let [first, tail @ ..] = self { Some((first, tail)) } else { None }
}
pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) {
unsafe { (self.get_unchecked(..mid), self.get_unchecked(mid..)) }
}
...
...
}
//原生指針 具體方法的實(shí)現(xiàn)摘要
impl<T: ?Sized> *const T {
pub const fn is_null(self) -> bool {
(self as *const u8).guaranteed_eq(null())
}
/// Casts to a pointer of another type.
pub const fn cast<U>(self) -> *const U {
self as _
}
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
if self.is_null() { None } else { unsafe { Some(&*self) } }
}
...
...
}
//原生數(shù)組指針 具體方法實(shí)現(xiàn)摘要。需要注意,原生數(shù)組指針也是原生指針,
//此處不應(yīng)該再實(shí)現(xiàn) *const T的同名函數(shù)。
impl<T> *const [T] {
pub const fn len(self) -> usize {
metadata(self)
}
pub const fn as_ptr(self) -> *const T {
self as *const T
}
...
...
}
// 對(duì)&A實(shí)現(xiàn)PartialEq<&B> Trait, 如果A實(shí)現(xiàn)了 PartialEQ<B>
impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &A
where
A: PartialEq<B>,
{
fn eq(&self, other: &&B) -> bool {
PartialEq::eq(*self, *other)
}
fn ne(&self, other: &&B) -> bool {
PartialEq::ne(*self, *other)
}
}
針對(duì)限制的泛型實(shí)現(xiàn)方法和Trait大幅的減少了代碼,受限制的泛型是RUST提供的強(qiáng)大的泛型語法。
編譯器內(nèi)置Trait代碼分析
分析編譯器內(nèi)置Trait源代碼發(fā)現(xiàn)源代碼文件中的大部分內(nèi)容實(shí)際上是參考文檔。
本節(jié)主要給出對(duì)參考文檔理解后的一些總結(jié)
//Send Trait
pub unsafe auto trait Send {
// empty.
}
//原生指針不支持Send Trait實(shí)現(xiàn),利用"!"表示明確的對(duì)Trait的不支持
impl<T: ?Sized> !Send for *const T {}
impl<T: ?Sized> !Send for *mut T {}
mod impls {
// 實(shí)現(xiàn)Sync的類型的類型不可變引用支持Send
unsafe impl<T: Sync + ?Sized> Send for &T {}
// 實(shí)現(xiàn)Send的類型的類型可變引用支持 Send
unsafe impl<T: Send + ?Sized> Send for &mut T {}
}
// Sync Trait
pub unsafe auto trait Sync {
// Empty
}
//原生指針不支持Sync Trait
impl<T: ?Sized> !Sync for *const T {}
impl<T: ?Sized> !Sync for *mut T {}
pub trait Sized {
// Empty.
}
//如果一個(gè)Sized的類型要強(qiáng)制轉(zhuǎn)換為動(dòng)態(tài)大小類型,那必須實(shí)現(xiàn)Unsize Trait
//例如 [T;N] 實(shí)現(xiàn)了 Unsize<[T]>
pub trait Unsize<T: ?Sized> {
// Empty.
}
//模式匹配表達(dá)式匹配時(shí)編譯器需要使用的Trait,如果一個(gè)結(jié)構(gòu)實(shí)現(xiàn)了PartialEq,該Trait會(huì)自動(dòng)被實(shí)現(xiàn)。
//推測(cè)這個(gè)結(jié)構(gòu)應(yīng)該是內(nèi)存按位比較
pub trait StructuralPartialEq {
// Empty.
}
//主要用于模式匹配,如果一個(gè)結(jié)構(gòu)實(shí)現(xiàn)了Eq, 該Trait會(huì)自動(dòng)被實(shí)現(xiàn)。
pub trait StructuralEq {
// Empty.
}
//Copy,略
pub trait Copy: Clone {
// Empty.
}
//統(tǒng)一實(shí)現(xiàn)原生類型對(duì)Copy Trait的支持
mod copy_impls {
use super::Copy;
macro_rules! impl_copy {
($($t:ty)*) => {
$(
impl Copy for $t {}
)*
}
}
impl_copy! {
usize u8 u16 u32 u64 u128
isize i8 i16 i32 i64 i128
f32 f64
bool char
}
impl Copy for ! {}
impl<T: ?Sized> Copy for *const T {}
impl<T: ?Sized> Copy for *mut T {}
impl<T: ?Sized> Copy for &T {}
//& mut T不支持Copy,以保證RUST的借用規(guī)則
}
//PhantomData被用來在類型結(jié)構(gòu)體中做一個(gè)標(biāo)記,標(biāo)記結(jié)構(gòu)體邏輯上存在但不必有實(shí)體的成員,成員類型表現(xiàn)在PhantomData的泛型里
//PhantomData具體闡述請(qǐng)參考標(biāo)準(zhǔn)庫文檔。
//PhantomData是個(gè)單元結(jié)構(gòu)體,單元結(jié)構(gòu)體的變量名就是單元結(jié)構(gòu)體的類型名。
//所以使用的時(shí)候直接使用PhantomData即可,編譯器會(huì)將泛型的類型實(shí)例化信息自動(dòng)帶入PhantomData中
pub struct PhantomData<T: ?Sized>;