Rust基礎(chǔ)學(xué)習(xí)-12-vector的使用

這一篇博客我們來(lái)聊一下Rust中 vector 的使用。vector 就像數(shù)組一樣,用于存儲(chǔ)同一類型的一系列的值,但是允許動(dòng)態(tài)地添加和刪除值,以及擁有一些其他的方法。

vector 的定義

在代碼中,使用 Vec<T> 來(lái)定義一個(gè) vector 類型的變量

fn main() {
  // 這一個(gè)可以動(dòng)態(tài)添加和刪除元素
    let mut vec1: Vec<u32> = Vec::new();
  
  // 在定義的時(shí)候就填充好值,因?yàn)闆](méi)有mut,所以無(wú)法動(dòng)態(tài)添加和刪除
  let vec2 = vec![1, 2, 3, 4, 5];
  let vec3 = vec!["str1", "str2", "str3"];
}

vec! 是rust提供的宏,可以動(dòng)態(tài)地根據(jù)我們的數(shù)據(jù),自動(dòng)推斷出這個(gè) vector 變量的類型

添加和刪除元素

vector 中添加元素,使用 push 方法,從vector中刪除最后添加的元素,使用 pop 方法

fn main() {
    let mut nums: Vec<u32> = Vec::new();
    nums.push(10);
    nums.push(11);
    nums.push(12);
    println!("{:?}", nums); // 打印出 [10, 11, 12]
    nums.pop(); // 將最后的元素拿出來(lái)丟了
    println!("{:?}", nums); // 這里打印出 [10, 11]
}

pop 會(huì)將值返回,返回的類型是 Option<T> 類型,我們可以定義一個(gè)變量接收 pop 出來(lái)的值

fn main() {
    let mut nums: Vec<u32> = Vec::new();
    nums.push(10);
    nums.push(11);
    nums.push(12);
    println!("{:?}", nums);
  
    let x = nums.pop();
    println!("x: {:?}", x);  // 這里將打印出 Some(12)
}

如果 vector 中已經(jīng)沒(méi)有元素,繼續(xù)使用 pop,將返回 Option<T> 中的 None

訪問(wèn)特定所以呢的元素

就像數(shù)組一樣,vector也可以使用 [index] 這樣的形式去訪問(wèn)某個(gè)元素,還可以使用 get(index) 方法訪問(wèn)。

fn main() {
    let mut nums: Vec<u32> = Vec::new();
    nums.push(10);
    nums.push(11);
    nums.push(12);

    // 這里獲取的是第0個(gè)元素的引用
    let first_num = &nums[0];
    println!("first_num: {}", first_num);
        
    // get 方法在這里返回的 Option<&u32>
    let second_num = nums.get(1);
    println!("x:{:?}", second_num);
}

如果我們嘗試訪問(wèn)越界索引的元素會(huì)怎樣呢?如果使用 [index] 這種形式,Rust 會(huì)直接導(dǎo)致 panic 然后退出進(jìn)程,如果使用 get(index) 這種形式,Rust會(huì)返回 Option<T> 中的 None

為什么這里獲取值的時(shí)候,要獲取它引用,而不是值本身呢?對(duì)于 copy 類型的數(shù)據(jù),似乎沒(méi)有什么區(qū)別,但是對(duì)于 String 這樣類型的數(shù)據(jù),如果我們直接獲取值,就會(huì)導(dǎo)致所有權(quán)的移動(dòng)??聪旅娴谋闅v代碼

遍歷 vector

fn main() {
    let mut names: Vec<String> = Vec::new();
    names.push("Jack".to_string());
    names.push("Tony".to_string());
    names.push("Tina".to_string());
    // 遍歷vector中每一個(gè)元素,然后打印出來(lái)
    for name in &names {
        println!("name: {}", name);
    }
        
    // 打印出整個(gè)vector來(lái)
    println!("names: {:?}", names);
}

上面的代碼,如果我們把第7行改為 for name in names 那么這段代碼就會(huì)編譯不過(guò),因?yàn)?vector 中的值的所有權(quán),已經(jīng)移動(dòng)到了 println 中的 name 變量,所以在第12行再次訪問(wèn)的時(shí)候,就會(huì)出錯(cuò),所以編譯器會(huì)直接編譯不過(guò)。所以,在獲取和遍歷 vector 中值的時(shí)候,一定要注意所有權(quán)轉(zhuǎn)移的問(wèn)題

在 vector 中存儲(chǔ)不同類型的值

在博客開(kāi)始的時(shí)候我們說(shuō) vector 只能存儲(chǔ)相同類型的值,這是沒(méi)錯(cuò)的。這里我們存儲(chǔ)不同類型的值,是使用了上一篇講到的枚舉類型而做到的??聪旅娴拇a

#[derive(Debug)]
enum Data {
    IData(i32),
    FData(f32),
    SData(String),
}

fn main() {
    let mut data_sets: Vec<Data> = Vec::new();
    data_sets.push(Data::IData(10));
    data_sets.push(Data::FData(3.14159));
    data_sets.push(Data::SData(String::from("Hello Rust"));
}

先定義一個(gè)擁有多種數(shù)據(jù)類型的枚舉,然后定義一個(gè)存儲(chǔ)這種枚舉類型的 vector,這樣就實(shí)現(xiàn)了一個(gè) vector 中存儲(chǔ)不同類型的數(shù)據(jù)。

Vec詳細(xì)使用時(shí),可以參考源代碼的文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容