柚子快報邀請碼778899分享:Rust學習筆記(Part
柚子快報邀請碼778899分享:Rust學習筆記(Part
1.mut給變量賦予可變性.
2.想使用外部包需要在Cargo.toml文件中添加依賴
3.調用rand::thread_rng函數(shù)生成隨機數(shù)(let secret_number = rand::thread_rng().gen_range(1..100);)
4.rust關鍵字:
as- 執(zhí)行原始轉換,消除包含項目的特定特征的歧義,或重命名use語句中的項目
async- 返回 aFuture而不是阻塞當前線程
await- 暫停執(zhí)行,直到結果Future準備好
break- 立即退出循環(huán)
const- 定義常量項或常量原始指針
continue- 繼續(xù)下一次循環(huán)迭代
crate- 在模塊路徑中,指的是包根
dyn- 動態(tài)調度至特征對象
else- 回退if和if let控制流構造
enum- 定義一個枚舉
extern- 鏈接外部函數(shù)或變量
false- 布爾值假文字
fn- 定義函數(shù)或函數(shù)指針類型
for- 循環(huán)遍歷迭代器中的項目,實現(xiàn)特征,或指定更高級別的生命周期
if- 根據(jù)條件表達式的結果進行分支
impl- 實現(xiàn)固有或特征功能
infor-循環(huán)語法的一部分
let- 綁定變量
loop- 無條件循環(huán)
match- 將值與模式匹配
mod- 定義一個模塊
move- 讓閉包擁有其所有捕獲的所有權
mut- 表示引用、原始指針或模式綁定中的可變性
pub- 表示結構字段、impl塊或模塊中的公共可見性
ref- 通過引用綁定
return- 從函數(shù)返回
Self- 我們正在定義或實現(xiàn)的類型的類型別名
self- 方法主題或當前模塊
static- 全局變量或生存期持續(xù)整個程序執(zhí)行
struct- 定義一個結構
super- 當前模塊的父模塊
trait- 定義一個特征
true- 布爾真文字
type- 定義類型別名或關聯(lián)類型
union- 定義聯(lián)合;僅在聯(lián)合聲明中使用時才是關鍵字
unsafe- 表示不安全的代碼、函數(shù)、特征或實現(xiàn)
use- 將符號納入范圍
where- 表示限制類型的子句
while- 根據(jù)表達式的結果進行條件循環(huán)
5.元組是一種將多個具有各種類型的值組合成一種復合類型的通用方法.元組的長度是固定的:
? 一旦聲明,它們的大小就不能增加或縮小
6.可以使用let將元組解構
7.另一種擁有多個值集合的方法是使用數(shù)組.與元組不同,數(shù)組的每個元素必須具有相同的類型.
? 與其他一些語言中的數(shù)組不同,Rust 中的數(shù)組具有固定長度.
8.使用方括號來編寫數(shù)組的類型 let a: [i32; 5] = [1, 2, 3, 4, 5];
9.通過指定初始值,后跟分號,然后在方括號中指定數(shù)組的長度,
? 來初始化一個數(shù)組,使其每個元素包含相同的值
? let a = [3; 5]; = let a = [3, 3, 3, 3, 3];
10.Rust 代碼使用蛇形命名法作為函數(shù)和變量名稱的常規(guī)樣式.其中所有字母均為小寫,并用下劃線分隔單詞.
11.函數(shù)單參和多參的定義
fn another_function(x: i32)
fn print_labeled_measurement(value: i32, unit_label: char)
12.語句是執(zhí)行某些操作但不返回值的指令.表達式求值得到結果值
13.表達式不包括結尾分號.如果在表達式末尾添加分號則會將其變成語句,然后它將不會返回值.
{
? ? let x = 3;//語句
? ? x + 1 //表達式
}
14.函數(shù)可以向調用它們的代碼返回值.不命名返回值但必須在箭頭 ( ->) 后聲明它們的類型
15.注釋:// 表示,可以放在代碼上方一行,也可以放在末尾.
16.if是一個表達式,我們可以在語句的右邊使用let來將結果賦給變量
17.Rust 有三種循環(huán):loop、while和for
18.在break用于停止循環(huán)的表達式后添加要返回的值,該值將在循環(huán)外返回
fn main() {
? ? let mut counter = 0;
? ? let result = loop {
? ? ? ? counter += 1;
? ? ? ? if counter == 10 {
? ? ? ? ? ? break counter * 2;
? ? ? ? }
? ? };
? ? println!("The result is {result}");
}
19.標簽:循環(huán)標簽用于消除多個循環(huán)之間的歧義
fn main() {
? ? let mut count = 0;
? ? 'counting_up: loop { ?//標簽
? ? ? ? println!("count = {count}");
? ? ? ? let mut remaining = 10;
? ? ? ? loop {
? ? ? ? ? ? println!("remaining = {remaining}");
? ? ? ? ? ? if remaining == 9 {
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? ? ? if count == 2 {
? ? ? ? ? ? ? ? break 'counting_up';//標簽
? ? ? ? ? ? }
? ? ? ? ? ? remaining -= 1;
? ? ? ? }
? ? ? ? count += 1;
? ? }
? ? println!("End count = {count}");
}
? ? 結果:
? ? count = 0
? ? remaining = 10
? ? remaining = 9
? ? count = 1
? ? remaining = 10
? ? remaining = 9
? ? count = 2
? ? remaining = 10
? ? End count = 2
? ? 外循環(huán)帶有標簽'counting_up,它會從 0 開始計數(shù)到 2.
? ? 沒有標簽的內循環(huán)會從 10 開始計數(shù)到 9.
? ? 第一個break不指定標簽的循環(huán)只會退出內循環(huán).
? ? 該break 'counting_up;語句會退出外循環(huán).
20.for循環(huán)簡潔操作,Range標準庫提供按順序生成所有數(shù)字從一個數(shù)字開始,在另一個數(shù)字之前結束.
21.Rust通過所有權系統(tǒng)管理內存
22.所有存儲在棧上的數(shù)據(jù)都必須有已知的固定大小.編譯時大小未知或大小可能會改變的數(shù)據(jù)必須存儲在堆上.
23.因為指向堆的指針是已知的固定大小,所以可以將指針存儲在堆棧上
24.推送到堆棧比在堆上分配更快,因為分配器永遠不必搜索存儲新數(shù)據(jù)的位置;該位置始終位于堆棧的頂部.
25.訪問堆中的數(shù)據(jù)比訪問堆棧中的數(shù)據(jù)要慢,因為必須遵循指針才能到達那里
26.所有權規(guī)則
? ? (1)Rust中的每個值都有一個所有者.
? ? (2)同一時間只能有一個所有者.
? ? (3)當所有者超出范圍時,該值將被刪除.
27.String類型,為了支持可變、可增長的文本,我們需要在堆上分配一定量的內存(編譯時未知)來保存內容
? ? 必須在運行時從內存分配器請求內存.
? ? 當我們完成操作后,我們需要一種方法來將String內存返回給分配器.
28.一旦擁有它的變量超出范圍,內存就會自動返回(Rust會為我們調用一個特殊函數(shù).這個函數(shù)稱為drop)
29.當s2和s1超出范圍時,它們都會嘗試釋放同一塊內存.這被稱為雙重釋放錯誤當s2和s1超出范圍時,
? ?它們都會嘗試釋放同一塊內存.這被稱為雙重釋放錯誤
? ? ?let s1 = String::from("hello");
? ? ?let s2 = s1;//把s1'移動'到s2,只有s2有效,超出范圍釋放內存.
30.Rust 永遠不會自動創(chuàng)建數(shù)據(jù)的“深層”副本.因此,可以認為任何自動 復制在運行時性能方面都是廉價的.
31.如果我們確實想深度復制String的堆數(shù)據(jù),而不僅僅是堆棧數(shù)據(jù),我們可以使用一種稱為clone的通用方法
? ? let s1 = String::from("hello");
? ? let s2 = s1.clone();
? ? println!("s1 = {s1}, s2 = {s2}");
32.在編譯時具有已知大小的類型(例如整數(shù))完全存儲在堆棧中,因此可以快速復制實際值
33.如果類型實現(xiàn)了該Copy 特征,則使用它的變量不會移動,而是被簡單地復制,使得它們在分配給另一個變量后仍然有效
? ? 所有整數(shù)類型,例如u32.
? ? 布爾類型,bool,其值為true和false.
? ? 所有浮點類型,例如f64.
? ? 字符類型,char.
? ? 元組,如果它們僅包含也實現(xiàn)Copy的類型.例如, (i32, i32)實現(xiàn)Copy,但(i32, String)不實現(xiàn).
34.引用就像指針,因為它是一個地址,我們可以跟蹤它來訪問存儲在該地址的數(shù)據(jù);該數(shù)據(jù)??由其他變量擁有.
? ?與指針不同,引用保證在該引用的生命周期內指向特定類型的有效值.
? ? fn main() {
? ? ? ? let s1 = String::from("hello");
? ? ? ? let len = calculate_length(&s1);
? ? ? ? println!("The length of '{s1}' is {len}.");
? ? }
? ? fn calculate_length(s: &String) -> usize {
? ? ? ? s.len()
? ? }
35.引用的值s1 但不擁有該值.由于它不擁有該值,因此當引用停止使用時,它指向的值不會被刪除.(不會被drop)
36.正如變量默認是不可變的,引用也是如此.不允許修改引用的東西.
37.調用函數(shù)的地方mut創(chuàng)建一個可變引用,可變引用有一個很大的限制:
? ?如果你有一個對某個值的可變引用,你就不能再有對該值的其他引用!
? ? let mut s = String::from("hello");
? ? let r1 = &mut s;
? ? let r2 = &mut s;
? ? println!("{}, {}", r1, r2);//編譯錯誤
38.數(shù)據(jù)競爭類似于競爭條件,當發(fā)生以下三種行為時會發(fā)生:
? ?兩個或多個指針同時訪問相同的數(shù)據(jù).
? ?至少有一個指針正用于寫入數(shù)據(jù).
? ?沒有使用任何機制來同步對數(shù)據(jù)的訪問.
39.空指針(指向可能已分配給其他人的內存位置的指針)
40.切片是一種引用,因此它沒有所有權.
41.將String使用該方法將其轉換為字節(jié)數(shù)組
? ?let bytes = s.as_bytes();
42.切片創(chuàng)建:[starting_index..ending_index]
43.starting_index是切片中的第一個位置,并且ending_index比切片中的最后一個位置多一個.
44. let s = String::from("hello");
? ? let slice = &s[0..2] == let slice = &s[..2];
? ? let len = s.len();
? ? let slice = &s[3..len];
? ? let slice = &s[3..];
45.取整個字符串:let slice = &s[..];
46.iter().enumerate() 方法對 bytes 數(shù)組進行迭代.這個方法會返回一個包含索引和對應值的元組.
47.s此處的類型為&str:它是指向二進制文件特定點的切片.這也是為什么字符串文字是不可變的;&str是不可變的引用.
48.該語法..指定未明確設置的其余字段應具有與給定實例中的字段相同的值.
? ? fn main() {
? ? // --snip--
? ? let user2 = User {
? ? ? ? email: String::from("another@example.com"),
? ? ? ? ..user1
? ? };
}
49. Rust確實包含打印調試信息的功能,但我們必須明確選擇讓該功能在我們的結構體中可用.
? ? 為此,我們#[derive(Debug)]在結構體定義之前添加 outer 屬性
50.Self返回類型和函數(shù)主體中的關鍵字是關鍵字后出現(xiàn)的類型的別名,要調用此關聯(lián)函數(shù),
? ?我們使用::帶有結構名稱的語法; let sq = Rectangle::square(3)
51.任何 IP 地址都可以是版本 4 或版本 6 地址,但不能同時是兩者.
? ?IP 地址的這一特性使得枚舉數(shù)據(jù)結構非常合適,因為枚舉值只能是其變體之一.
? ? enum IpAddrKind {
? ? V4,
? ? V6,
? ? }
52.枚舉的變體在其標識符下命名空間,我們使用雙冒號將兩者分開.
? ?因為現(xiàn)在兩個值 IpAddrKind::V4和IpAddrKind::V6都是同一類型:IpAddrKind.
? ? let four = IpAddrKind::V4;
? ? let six = IpAddrKind::V6;
53. 直接將數(shù)據(jù)附加到枚舉的每個變體,因此不需要額外的結構
? ? enum IpAddr {
? ? ? ? V4(String),
? ? ? ? V6(String),
? ? }
? ? let home = IpAddr::V4(String::from("127.0.0.1"));
? ? let loopback = IpAddr::V6(String::from("::1"));
54.使用枚舉而不是結構還有另一個優(yōu)勢:每個變體可以具有不同類型和數(shù)量的關聯(lián)數(shù)據(jù).
? ?版本 4 IP 地址將始終具有四個數(shù)字組件,其值介于 0 到 255 之間.
? ?如果我們想將V4地址存儲為四個u8值,但仍將V6地址表示為一個String值,則無法使用結構
? ? enum IpAddr {
? ? ? ? V4(u8, u8, u8, u8),
? ? ? ? V6(String),
? ? }
? ? let home = IpAddr::V4(127, 0, 0, 1);
? ? let loopback = IpAddr::V6(String::from("::1"));
55.可以將任何類型的數(shù)據(jù)放入枚舉變量中:例如字符串、數(shù)字類型或結構.甚至可以包含另一個枚舉
56.match的強大之處在于模式的表達能力以及編譯器確認所有可能的情況都得到處理的事實.
? ? enum Coin {
? ? Penny,
? ? Nickel,
? ? Dime,
? ? Quarter,
? ? }
? ? fn value_in_cents(coin: Coin) -> u8 {
? ? ? ? match coin {
? ? ? ? ? ? Coin::Penny => 1,
? ? ? ? ? ? Coin::Nickel => 5,
? ? ? ? ? ? Coin::Dime => 10,
? ? ? ? ? ? Coin::Quarter => 25,
? ? ? ? }
? ? }
57.如果匹配分支代碼較短,我們通常不使用花括號,其中每個分支僅返回一個值.
? ?如果要在匹配分支中運行多行代碼,則必須使用花括號,分支后面的逗號是可選的
? ? ? ? Coin::Penny => {
? ? ? ? println!("Lucky penny!");
? ? ? ? 1
? ? }
58.匹配分支的另一個有用功能是它們可以綁定到與模式匹配的值的部分
? ?假設一位朋友想收集所有 50 個州的 25 美分硬幣.當我們按硬幣類型對零錢進行分類時,
? ?我們還會標出與每個 25 美分硬幣相關的州名,這樣如果我們的朋友沒有這個州的 25 美分硬幣,
? ?他們就可以將其添加到他們的收藏中.
? ?在此代碼的 match 表達式中,我們向state模式添加一個名為的變量,該變量與變體的值匹配Coin::Quarter.
? ?當 Coin::Quarter匹配時,state變量將綁定到該季度的狀態(tài)值.
? ?fn value_in_cents(coin: Coin) -> u8 {
? ? match coin {
? ? ? ? Coin::Penny => 1,
? ? ? ? Coin::Nickel => 5,
? ? ? ? Coin::Dime => 10,
? ? ? ? Coin::Quarter(state) => {
? ? ? ? ? ? println!("State quarter from {state:?}!");
? ? ? ? ? ? 25
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? 如果我們調用value_in_cents(Coin::Quarter(UsState::Alaska)),
? ? coin 則為Coin::Quarter(UsState::Alaska)
59.Rust 還有一個模式,當我們想要一個 catch-all 但不想catch-all使用 模式中的值時,可以使用它:_
? ?這是一個特殊的模式,它匹配任何值并且不綁定到該值.這告訴 Rust 我們不會使用該值,
? ?因此 Rust 不會警告我們未使用的變量.
60.如果程序中的邏輯過于冗長而無法使用 來表達match可以使用if let
61.包有兩種形式:二進制包或庫包, 二進制包是可以編譯為可運行的可執(zhí)行文件的程序,例如命令行程序或服務器,
? ?每個包都必須有一個main函數(shù)來定義可執(zhí)行文件運行時會發(fā)生什么
62.庫包沒有main函數(shù),也不會編譯為可執(zhí)行文件,相反,它們定義旨在與多個項目共享的功能
63.一個包可以包含任意數(shù)量的二進制包,但最多只能包含一個庫包,一個包必須至少包含一個包,無論是庫包還是二進制包
64.從包根開始:當編譯包時,編譯器首先在包根文件(對于庫包 通常為 src/lib.rs ,對于二進制包通常為src/main.rs )
? ?中查找要編譯的代碼,聲明模塊:在 crate 根文件中,可以聲明新模塊;
? ?例如,使用mod garden聲明一個“garden”模塊;,編譯器將在以下位置查找模塊的代碼:
? ?內聯(lián),在大括號內替換后面的分號mod garden
? ?在文件src/garden.rs中
? ?在文件src/garden/mod.rs中
? ?聲明子模塊:在除 crate 根目錄之外的任何文件中,都可以聲明子模塊,
? ?例如,可以在src/garden.rs中聲明mod vegetables,編譯器將在以下位置的父模塊目錄中查找子模塊的代碼:
? ?內聯(lián),直接跟在mod vegetables, 后面,用花括號括起來,而不是分號
? ?在文件src/garden/vegetables.rs中
? ?在文件src/garden/vegetables/mod.rs中
? ?模塊中的代碼路徑:一旦模塊成為包的一部分,就可以使用代碼路徑從同一包中的任何其他位置引用該模塊中的代碼,
? ?只要隱私規(guī)則允許,例如, 花園蔬菜模塊中的Asparagus類型可以在crate::garden::vegetables::Asparagus處找到
? ?私有與公共:默認情況下,模塊內的代碼對于其父模塊而言是私有的,要將模塊設為公共,
? ?請使用 而pub mod而不是mod來聲明它,要將公共模塊中的項目也設為公共,pub使用在其聲明前,
? ?關鍵字use:在范圍內,use關鍵字為項創(chuàng)建快捷方式以減少長路徑的重復,
? ?在任何可以引用的范圍內 crate::garden::vegetables::Asparagus,都可以使用use創(chuàng)建快捷方式,
? ?從那時use crate::garden::vegetables::Asparagus;起,只需要Asparagus在范圍內寫入以使用該類型即可
65.模塊還可以保存其他項目的定義,例如結構體、枚舉、常量、特征以及函數(shù)
66.如果模塊 A 包含在模塊 B 內,我們說模塊 A 是模塊 B 的子模塊,模塊 B 是模塊 A 的父模塊,
? ?請注意,整個模塊樹都植根于名為crate的隱式模塊下
67.絕對路徑是從包根開始的完整路徑;對于來自外部包的代碼,絕對路徑以包名稱開頭,而對于來自當前包的代碼,
? ?絕對路徑以文字crate開頭
? ? crate::front_of_house::hosting::add_to_waitlist();
? ?相對路徑從當前模塊開始,并使用self、super或當前模塊中的標識符
? ? front_of_house::hosting::add_to_waitlist();
68.絕對路徑和相對路徑后面都跟有一個或多個用雙冒號 ( ::) 分隔的標識符
69.父模塊中的項目不能使用子模塊中的私有項目,但子模塊中的項目可以使用其祖先模塊中的項目
70.將模塊公開并不會使其內容公開
71.模塊上的pub關鍵字僅允許其祖先模塊中的代碼引用它,而不能訪問其內部代碼.因為模塊是容器,
? ?所以僅將模塊公開我們能做的事情不多;我們需要更進一步,選擇將模塊中的一個或多個項目也公開.
72.私有規(guī)則適用于結構、枚舉、函數(shù)和方法以及模塊.
73.使用super允許我們引用我們知道在父模塊中的項目,當模塊與父模塊緊密相關但父模塊可能
? ?有一天會移動到模塊樹的其他位置時,這可以使重新排列模塊樹更容易
? ?fn deliver_order() {}
? ? mod back_of_house {
? ? ? ? fn fix_incorrect_order() {
? ? ? ? ? ? cook_order();
? ? ? ? ? ? super::deliver_order();
? ? ? ? }
? ? ? ? fn cook_order() {}
? ? }
74.我們還可以使用pub將結構體和枚舉指定為公共的,將結構體設為公共的,但結構體的字段仍然是私有的,
? ?可以根據(jù)具體情況將每個字段設為公共的或不公共的
? ?mod back_of_house {
? ? pub struct Breakfast {
? ? ? ? pub toast: String,
? ? ? ? seasonal_fruit: String,
? ? }
? ? impl Breakfast {
? ? ? ? pub fn summer(toast: &str) -> Breakfast {
? ? ? ? ? ? Breakfast {
? ? ? ? ? ? ? ? toast: String::from(toast),
? ? ? ? ? ? ? ? seasonal_fruit: String::from("peaches"),
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
75.將枚舉設為公共的,則它的所有變量都是公共的
? ? mod back_of_house {
? ? pub enum Appetizer {
? ? ? ? Soup,
? ? ? ? Salad,
? ? ? ? }
? ? }
? ? pub fn eat_at_restaurant() {
? ? ? ? let order1 = back_of_house::Appetizer::Soup;
? ? ? ? let order2 = back_of_house::Appetizer::Salad;
? ? }
76.使用use關鍵字引用路徑
? ? use crate::front_of_house::hosting;
? ? pub fn eat_at_restaurant() {
? ? ? ? hosting::add_to_waitlist();
? ? }
77.當使用use引入結構體、枚舉和其他項時,指定完整路徑是慣用方法
? ? use std::collections::HashMap
? ? fn main() {
? ? ? ? let mut map = HashMap::new();
? ? ? ? map.insert(1, 2);
? ? }
78.使用as解決將兩個同名類型帶入同一作用域
? ? use std::fmt::Result;
? ? use std::io::Result as IoResult;
? ? fn function1() -> Result {
? ? ? ? // --snip--
? ? }
? ? fn function2() -> IoResult<()> {
? ? ? ? // --snip--
? ? }
79.當使用use關鍵字將名稱帶入范圍時,新范圍中可用的名稱是私有的.為了使調用我們代碼的代碼能夠引用該名稱,
? ?就好像它是在該代碼的范圍中定義的一樣,可以組合pub和use
? ? mod front_of_house {
? ? pub mod hosting {
? ? ? ? pub fn add_to_waitlist() {}
? ? }
? ? }
? ? pub use crate::front_of_house::hosting;
? ? pub fn eat_at_restaurant() {
? ? ? ? hosting::add_to_waitlist();
? ? }
80.使用use嵌套路徑清理大型列表
? ? use std::cmp::Ordering;
? ? use std::io;
? ? ? ? ||
? ? use std::{cmp::Ordering, io};
? ? use std::io;
? ? use std::io::Write;
? ? ? ? ||
? ? use std::io::{self, Write}; ? ?
81.將路徑中定義的所有公共項目納入范圍
? ? use std::collections::*;
82.向量Vec
? ? let v = vec![1, 2, 3];
? ? let mut v = Vec::new();
? ? v.push(5);
? ? v.push(6);
? ? v.push(7);
? ? v.push(8);
83.向量是按數(shù)字索引的,從零開始.使用&和[] 為我們提供對索引值處元素的引用.
? ?當我們使用get 將索引作為參數(shù)傳遞的方法時,我們會得到一個Option<&T>可以與一起使用的match.
? ? let v = vec![1, 2, 3, 4, 5];
? ? let third: &i32 = &v[2];
? ? println!("The third element is {third}");
? ? let third: Option<&i32> = v.get(2);
? ? match third {
? ? ? ? Some(third) => println!("The third element is {third}"),
? ? ? ? None => println!("There is no third element."),
? ? }
84.第一種[]方法將導致程序崩潰,因為它引用了一個不存在的元素.
? ?當您希望程序在嘗試訪問向量末尾以外的元素時崩潰時,最好使用此方法
? ?當get方法傳遞一個向量之外的索引時,它會返回 None而不會崩潰
? ? let v = vec![1, 2, 3, 4, 5];
? ? let does_not_exist = &v[100];
? ? let does_not_exist = v.get(100);
85.向量將值在內存中彼此相鄰地放置,如果向量當前存儲的位置沒有足夠的空間將所有元素彼此相鄰地放置,
? ?則在向量末尾添加新元素可能需要分配新內存并將舊元素復制到新空間.在這種情況下,
? ?對第一個元素的引用將指向已釋放的內存.借用規(guī)則可防止程序陷入這種情況
? ?(原理:當程序有一個有效引用時,借用檢查器會強制執(zhí)行所有權和借用規(guī)則)
86.迭代可變向量中每個元素的可變引用,以便更改所有元素
? ? let mut v = vec![100, 32, 57];
? ? for i in &mut v {
? ? ? ? *i += 50;
? ? }
87.字符串創(chuàng)建: ? ?
? ? let mut s = String::new();
? ? let data = "initial contents";
? ? let s = data.to_string();
? ? // the method also works on a literal directly:
? ? let s = "initial contents".to_string();
88.還可以使用函數(shù)從字符串字面量String::from創(chuàng)建一個String
? ? let s = String::from("initial contents");
89.使用push_str和push附加到字符串(不獲得參數(shù)所有權)
? ? let mut s = String::from("foo");
? ? s.push_str("bar");
? ? let mut s = String::from("lo");
? ? s.push('l');
90.合并兩個現(xiàn)有的字符串.一種方法是使用+運算符,對于更復雜的字符串組合,我們可以改用宏format!
? ? let s1 = String::from("tic");
? ? let s2 = String::from("tac");
? ? let s3 = String::from("toe");
? ? let s = format!("{s1}-{s2}-{s3}");
91.Rust 字符串不支持索引
92.除了使用[]單個數(shù)字進行索引之外,您還可以使用[]范圍來創(chuàng)建包含特定字節(jié)的字符串切片:
? ? let hello = "Здравствуйте";
? ? let s = &hello[0..4];
這里,s將是 ,&str包含字符串的前 4 個字節(jié).每個字符都是 2 個字節(jié),這意味著 s將是Зд.
93.如果嘗試使用類似的方法僅切分字符字節(jié)的一部分 &hello[0..1],
? ?Rust 會在運行時產生恐慌,就像在向量中訪問無效索引一樣
94.創(chuàng)建空哈希表的一種方法是使用new并添加元素 insert.
? ? use std::collections::HashMap;
? ? let mut scores = HashMap::new();
? ? scores.insert(String::from("Blue"), 10);
? ? scores.insert(String::from("Yellow"), 50);
95.和向量一樣,哈希映射將數(shù)據(jù)存儲在堆上.這HashMap具有 類型的鍵String和 類型的值i32.
? ?和向量一樣,哈希映射是同質的:所有鍵必須具有相同的類型,并且所有值必須具有相同的類型
96.可以通過get向該方法提供其鍵來從哈希映射中獲取一個值
97.Copy對于實現(xiàn)了特征的類型,比如i32,值會被復制到哈希映射中.對于擁有的值,
? ?比如String,值會被移動,而哈希映射將成為這些值的所有者
98.如果將一個鍵和一個值插入到哈希映射中,然后插入具有不同值的相同鍵,則與該鍵關聯(lián)的值將被替換
99.僅當不存在鍵時才添加鍵和值
100.哈希映射有一個專門的 API,名為entry,它將要檢查的鍵作為參數(shù).該entry方法的返回值是一個枚舉,
? ?名為Entry,表示可能存在也可能不存在的值
? ? use std::collections::HashMap;
? ? let mut scores = HashMap::new();
? ? scores.insert(String::from("Blue"), 10);
? ? scores.entry(String::from("Yellow")).or_insert(50);
? ? scores.entry(String::from("Blue")).or_insert(50);
? ? println!("{scores:?}");
參考資料:Hello Cargo.
柚子快報邀請碼778899分享:Rust學習筆記(Part
精彩鏈接
本文內容根據(jù)網絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉載請注明,如有侵權,聯(lián)系刪除。