最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Rust語(yǔ)言中級(jí)教程之指針

 更新時(shí)間:2023年05月06日 16:09:37   作者:QIAOPENGJUN  
Rust中共有三種類型的指針,分別為引用,解引用,智能指針,這篇文章主要介紹了Rust語(yǔ)言中級(jí)教程之指針,需要的朋友可以參考下

Rust語(yǔ)言中級(jí)教程

一、指針

什么是指針

  • 指針是計(jì)算機(jī)引用無(wú)法立即直接訪問(wèn)的數(shù)據(jù)的一種方式(類比 書的目錄)
  • 數(shù)據(jù)在物理內(nèi)存(RAM)中是分散的存儲(chǔ)著
  • 地址空間是檢索系統(tǒng)
  • 指針就被編碼為內(nèi)存地址,使用 usize 類型的整數(shù)表示。
    • 一個(gè)地址就會(huì)指向地址空間中的某個(gè)地方
  • 地址空間的范圍是 OS 和 CPU 提供的外觀界面
    • 程序只知道有序的字節(jié)序列,不會(huì)考慮系統(tǒng)中實(shí)際 RAM 的數(shù)量

名詞解釋

  • 內(nèi)存地址(地址),就是指代內(nèi)存中單個(gè)字節(jié)的一個(gè)數(shù)
    • 內(nèi)存地址是匯編語(yǔ)言提供的抽象
  • 指針(有時(shí)擴(kuò)展稱為原始指針),就是指向某種類型的一個(gè)內(nèi)存地址
    • 指針是高級(jí)語(yǔ)言提供的抽象
  • 引用,就是指針。如果是動(dòng)態(tài)大小的類型,就是指針和具有額外保證的一個(gè)整數(shù)
    • 引用是 Rust 提供的抽象

Rust 的引用

  • 引用始終引用的是有效數(shù)據(jù)
  • 引用與 usize 的倍數(shù)對(duì)齊
  • 引用可以為動(dòng)態(tài)大小的類型提供上述保障

Rust 的引用 和 指針

static B: [u8; 10] = [99, 97, 114, 114, 121, 116, 111, 119, 101, 108];
static C: [u8; 11] = [116, 104, 97, 110, 107, 115, 102, 105, 115, 104, 0];
fn main() {
    let a = 42;
    let b = &B;
    let c = &C;
    println!("a: {}, b: {:p}, c: {:p}", a, b, c);
}

運(yùn)行

point_demo on  master [?] is ?? 0.1.0 via ?? 1.67.1 via ?? base 
? cargo run           
   Compiling point_demo v0.1.0 (/Users/qiaopengjun/rust/point_demo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.44s
     Running `target/debug/point_demo`
a: 42, b: 0x1023dc660, c: 0x1023dc66a

point_demo on  master [?] is ?? 0.1.0 via ?? 1.67.1 via ?? base 

  • 一個(gè)更加逼真的例子
    • 使用更復(fù)雜的類型展示指針內(nèi)部的區(qū)別
use std::mem::size_of;
static B: [u8; 10] = [99, 97, 114, 114, 121, 116, 111, 119, 101, 108];
static C: [u8; 11] = [116, 104, 97, 110, 107, 115, 102, 105, 115, 104, 0];
fn main() {
    // let a = 42;
    // let b = &B;
    // let c = &C;
    // println!("a: {}, b: {:p}, c: {:p}", a, b, c);
    let a: usize = 42;
    let b: Box<[u8]> = Box::new(B);
    let c: &[u8; 11] = &C;
    println!("a (unsigned 整數(shù)):");
    println!("  地址: {:p}", &a);
    println!("  大小:    {:?} bytes", size_of::<usize>());
    println!("  值:  {:?}\n", a);
    println!("b (B 裝在 Box 里):");
    println!("  地址:  {:p}", &b);
    println!("  大小:    {:?} bytes", size_of::<Box<[u8]>>());
    println!("  指向:  {:p}\n", b);
    println!("c (C 的引用):");
    println!("  地址:  {:p}", &c);
    println!("  大小:  {:?} bytes", size_of::<&[u8; 11]>());
    println!("  指向:  {:p}\n", c);
    println!("B (10 bytes 的數(shù)組):");
    println!("  地址:  {:p}", &B);
    println!("  大小:  {:?} bytes", size_of::<[u8; 10]>());
    println!("  值:  {:?}\n", B);
    println!("C (11 bytes 的數(shù)字):");
    println!("  地址:  {:p}", &C);
    println!("  大小:  {:?} bytes", size_of::<[u8; 11]>());
    println!("  值:  {:?}\n", C);
}

運(yùn)行

point_demo on  master [?] is ?? 0.1.0 via ?? 1.67.1 via ?? base 
? cargo run
   Compiling point_demo v0.1.0 (/Users/qiaopengjun/rust/point_demo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.19s
     Running `target/debug/point_demo`
a (unsigned 整數(shù)):
  地址: 0x16dda9a08
  大小:    8 bytes
  值:  42

b (B 裝在 Box 里):
  地址:  0x16dda9a10
  大小:    16 bytes
  指向:  0x12b606ba0

c (C 的引用):
  地址:  0x16dda9a30
  大小:  8 bytes
  指向:  0x10208d7ba

B (10 bytes 的數(shù)組):
  地址:  0x10208d7b0
  大小:  10 bytes
  值:  [99, 97, 114, 114, 121, 116, 111, 119, 101, 108]

C (11 bytes 的數(shù)字):
  地址:  0x10208d7ba
  大小:  11 bytes
  值:  [116, 104, 97, 110, 107, 115, 102, 105, 115, 104, 0]

point_demo on  master [?] is ?? 0.1.0 via ?? 1.67.1 via ?? base 

  • 對(duì) B 和 C 中文本進(jìn)行解碼的例子
    • 它創(chuàng)建了一個(gè)與前圖更加相似的內(nèi)存地址布局
use std::borrow::Cow;
use std::ffi::CStr;
use std::os::raw::c_char;
static B: [u8; 10] = [99, 97, 114, 114, 121, 116, 111, 119, 101, 108];
static C: [u8; 11] = [116, 104, 97, 110, 107, 115, 102, 105, 115, 104, 0];
fn main() {
  let a = 42;
  let b: String;
  let c: Cow<str>;
  unsafe {
    let b_ptr = &B as * const u8 as *mut u8;
    b = String::from_raw_parts(b_ptr, 10, 10);
    let c_ptr = &C as *const u8 as *const c_char;
    c = CStr::from_ptr(c_ptr).to_string_lossy();
  }
  println!("a: {}, b: {}, c: {}", a, b, c);
}

Raw Pointers(原始指針)

  • Raw Pointer (原始指針)是沒有 Rust 標(biāo)準(zhǔn)保障的內(nèi)存地址。
    • 這些本質(zhì)上是 unsafe 的
  • 語(yǔ)法:
    • 不可變 Raw Pointer:*const T
    • 可變的 Raw Pointer:*mut T
    • 注意:*const T,這三個(gè)標(biāo)記放在一起表示的是一個(gè)類型
    • 例子:*const String
  • *const T 與 *mut T 之間的差異很小,相互可以自由轉(zhuǎn)換
  • Rust 的引用(&mut T 和 &T)會(huì)編譯為原始指針
    • 這意味著無(wú)需冒險(xiǎn)進(jìn)入 unsafe 塊,就可以獲得原始指針的性能
  • 例子:把引用轉(zhuǎn)為原始指針
fn main() {
  let a: i64 = 42;
  let a_ptr = &a as *const i64;
  println!("a: {} ({:p})", a, a_ptr);
}
  • 解引用(dereference):通過(guò)指針從 RAM 內(nèi)存提取數(shù)據(jù)的過(guò)程叫做對(duì)指針進(jìn)行解引用(dereferencing a pointer)
  • 例子:把引用轉(zhuǎn)為原始指針
fn main() {
  let a: i64 = 42;
  let a_ptr = &a as *const i64;
  let a_addr: usize = unsafe {std::mem::transmute(a_ptr)};
  println!("a: {} ({:p}...0x{:x})", a, a_ptr, a_addr + 7);
}

關(guān)于 Raw Pointer 的提醒

  • 在底層,引用(&T 和 &mutT)被實(shí)現(xiàn)為原始指針。但引用帶有額外的保障,應(yīng)該始終作為首選使用
  • 訪問(wèn) Raw Pointer 的值總是 unsafe 的
  • Raw Pointer 不擁有值的所有權(quán)
    • 在訪問(wèn)時(shí)編譯器不會(huì)檢查數(shù)據(jù)的合法性
  • 允許多個(gè) Raw Pointer 指向同一數(shù)據(jù)
    • Rust 無(wú)法保證共享數(shù)據(jù)的合法性

使用 Raw Pointer 的情況

  • 不可避免
    • 某些 OS 或 第三方庫(kù)需要使用,例如與C交互
  • 共享對(duì)某些內(nèi)容的訪問(wèn)至關(guān)重要,運(yùn)行時(shí)性能要求高

Rust 指針生態(tài)

  • Raw Pointer 是 unsafe 的
  • Smart Pointer(智能指針)傾向于包裝原始指針,附加更多的能力
    • 不僅僅是對(duì)內(nèi)存地址解引用

Rust 智能指針

名稱簡(jiǎn)介強(qiáng)項(xiàng)弱項(xiàng)
Raw Pointer*mut T 和 *const T,自由基,閃電般塊,極其 Unsafe速度、與外界交互Unsafe
Box<T>可把任何東西都放在Box里??山邮軒缀跞魏晤愋偷拈L(zhǎng)期存儲(chǔ)。新的安全編程時(shí)代的主力軍。將值集中存儲(chǔ)在 Heap大小增加
Rc<T>是Rust的能干而吝嗇的簿記員。它知道誰(shuí)借了什么,何時(shí)借了什么對(duì)值的共享訪問(wèn)大小增加;運(yùn)行時(shí)成本;線程不安全
Arc<T>是Rust的大使。它可以跨線程共享值,保證這些值不會(huì)相互干擾對(duì)值的共享訪問(wèn);線程安全大小增加;運(yùn)行時(shí)成本
Cell<T>變態(tài)專家,具有改變不可變值的能力內(nèi)部可變性大小增加;性能
RefCell<T>對(duì)不可變引用執(zhí)行改變,但有代價(jià)內(nèi)部可變性;可與僅接受不可變引用的Rc、Arc嵌套使用大小增加;運(yùn)行時(shí)成本;缺乏編譯時(shí)保障
Cow<T>封閉并提供對(duì)借用數(shù)據(jù)的不可變?cè)L問(wèn),并在需要修改或所有權(quán)時(shí)延遲克隆數(shù)據(jù)當(dāng)只是只讀訪問(wèn)時(shí)避免寫入大小可能會(huì)增大
String可處理可變長(zhǎng)度的文本,展示了如何構(gòu)建安全的抽象動(dòng)態(tài)按需增長(zhǎng);在運(yùn)行時(shí)保證正確編碼過(guò)度分配內(nèi)存大小
Vec<T>程序最常用的存儲(chǔ)系統(tǒng);它在創(chuàng)建和銷毀值時(shí)保持?jǐn)?shù)據(jù)有序動(dòng)態(tài)按需增長(zhǎng)過(guò)度分配內(nèi)存大小
RawVec<T>Vec<T>和其它動(dòng)態(tài)大小類型的基石;知道如何按需給你的數(shù)據(jù)提供一個(gè)家動(dòng)態(tài)按需增長(zhǎng);與內(nèi)存分配器一起配合尋找空間不直接適用于您的代碼
Unique<T>作為值的唯一所有者,可保證擁有完全控制權(quán)需要獨(dú)占值的類型(如 String)的基礎(chǔ)不適合直接用于應(yīng)用程序代碼
Shared<T>分享所有權(quán)很難,但他使生活更輕松共享所有權(quán);可以將內(nèi)存與T的寬度對(duì)齊,即使是空的時(shí)候不適合直接用于應(yīng)用程序代碼

到此這篇關(guān)于Rust語(yǔ)言中級(jí)教程之指針的文章就介紹到這了,更多相關(guān)Rust指針內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • RUST語(yǔ)言函數(shù)的定義與調(diào)用方法

    RUST語(yǔ)言函數(shù)的定義與調(diào)用方法

    定義一個(gè)RUST函數(shù)使用fn關(guān)鍵字,下面通過(guò)本文給大家介紹RUST語(yǔ)言函數(shù)的定義與調(diào)用方法,感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • 一文弄懂rust生命周期

    一文弄懂rust生命周期

    生命周期是Rust語(yǔ)言中的一個(gè)概念,用于決內(nèi)存安全問(wèn)題,本文主要介紹了一文弄懂rust生命周期,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • Rust如何進(jìn)行模塊化開發(fā)技巧分享

    Rust如何進(jìn)行模塊化開發(fā)技巧分享

    Rust模塊化,模塊化有助于代碼的管理和層次邏輯的清晰,本文主要介紹了Rust如何進(jìn)行模塊化開發(fā),結(jié)合實(shí)例代碼給大家講解的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • Rust 中的文件操作示例詳解

    Rust 中的文件操作示例詳解

    Rust 中的路徑操作是跨平臺(tái)的,std::path 模塊提供的了兩個(gè)用于描述路徑的類型,本文給大家介紹Rust 中的文件操作示例詳解,感興趣的朋友一起看看吧
    2021-11-11
  • Rust并發(fā)編程之使用消息傳遞進(jìn)行線程間數(shù)據(jù)共享方式

    Rust并發(fā)編程之使用消息傳遞進(jìn)行線程間數(shù)據(jù)共享方式

    文章介紹了Rust中的通道(channel)概念,包括通道的基本概念、創(chuàng)建并使用通道、通道與所有權(quán)、發(fā)送多個(gè)消息以及多發(fā)送端,通道提供了一種線程間安全的通信機(jī)制,通過(guò)所有權(quán)規(guī)則確保數(shù)據(jù)安全,并且支持多生產(chǎn)者單消費(fèi)者架構(gòu)
    2025-02-02
  • 詳解Rust編程中的共享狀態(tài)并發(fā)執(zhí)行

    詳解Rust編程中的共享狀態(tài)并發(fā)執(zhí)行

    雖然消息傳遞是一個(gè)很好的處理并發(fā)的方式,但并不是唯一一個(gè),另一種方式是讓多個(gè)線程擁有相同的共享數(shù)據(jù),本文給大家介紹Rust編程中的共享狀態(tài)并發(fā)執(zhí)行,感興趣的朋友一起看看吧
    2023-11-11
  • 詳解Rust中的workspace

    詳解Rust中的workspace

    這篇文章主要向大家介紹Rust中的workspace,主要內(nèi)容包括基礎(chǔ)應(yīng)用、實(shí)用技巧、原理機(jī)制等方面,這個(gè)概念在Rust中是通用的,只不過(guò)maven換成了cargo,而模塊變成了crate,下面跟著小編通過(guò)一個(gè)例子給大家介紹下
    2022-03-03
  • Rust 語(yǔ)言中的 into() 方法及代碼實(shí)例

    Rust 語(yǔ)言中的 into() 方法及代碼實(shí)例

    在 Rust 中,into() 方法通常用于將一個(gè)類型的值轉(zhuǎn)換為另一個(gè)類型,這通常涉及到資源的所有權(quán)轉(zhuǎn)移,本文給大家介紹Rust 語(yǔ)言中的 into() 方法及代碼實(shí)例,感謝的朋友跟隨小編一起看看吧
    2024-03-03
  • 一文弄懂rust聲明宏

    一文弄懂rust聲明宏

    Rust支持兩種宏,一種是聲明宏,一種是過(guò)程宏,本文主要介紹了一文弄懂rust聲明宏,通過(guò)聲明宏可以減少一些樣板代碼,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • C和Java沒那么香了,Serverless時(shí)代Rust即將稱王?

    C和Java沒那么香了,Serverless時(shí)代Rust即將稱王?

    Serverless Computing,即”無(wú)服務(wù)器計(jì)算”,其實(shí)這一概念在剛剛提出的時(shí)候并沒有獲得太多的關(guān)注,直到2014年AWS Lambda這一里程碑式的產(chǎn)品出現(xiàn)。Serverless算是正式走進(jìn)了云計(jì)算的舞臺(tái)
    2021-06-06

最新評(píng)論

佛冈县| 虹口区| 华蓥市| 介休市| 汝城县| 哈巴河县| 小金县| 凤台县| 雅安市| 天峨县| 岳阳县| 瑞昌市| 盱眙县| 宁安市| 玉龙| 湘西| 崇礼县| 安泽县| SHOW| 临夏市| 托克逊县| 卓资县| 合水县| 社旗县| 绥棱县| 石阡县| 方山县| 蒙山县| 扎鲁特旗| 华阴市| 邵武市| 安多县| 鄂托克旗| 濮阳市| 吴堡县| 晋江市| 昭苏县| 英德市| 霍城县| 辽宁省| 黎城县|