Rust 學(xué)習(xí)筆記 ---記錄用
cargo相關(guān)
cargo new [project_name]
cargo build
cargo check? // 速度快
cargo run? ?
rust 難學(xué),難學(xué) ,難學(xué)
rust 安全 ,啥都安全?
rust 語法糖還行 ,感覺有像腳本語言?
rust 速度挺快?
打印hello world! : println!("hello world !");
1. 變量和可變性??
let 聲明一個(gè)變量??
mut 聲明一個(gè)變量為可變的變量,
若不聲明默認(rèn)是不可變的變量
定義格式? : let mut a:i32 = 123 ;? ?
let [mut][name][type] = [value] ;
?要么指定值 ,要么指定類型? (強(qiáng)類型語言,編譯器必須知道每一個(gè)變量是啥類型)??
2. 數(shù)組類型 分為標(biāo)量和復(fù)合類型
標(biāo)量:整形、浮點(diǎn)、布爾、字符
? 整形:u 無符號(hào) i有符號(hào)? u8, i8 ~~u128 i128? isize usize(64位或32位,系統(tǒng)的位數(shù))
? 浮點(diǎn):f32 f64?
? 數(shù)值運(yùn)算:+ - * / %?
? 布爾運(yùn)算:&& || !
? 復(fù)合運(yùn)算符 : += -= *= /= %=?
復(fù)合類型:原生復(fù)合(元組合數(shù)組)??
1, 元組? ()? 定長(zhǎng)? ?元祖可以解構(gòu)賦值給變量 , 每個(gè)元素不必相同
可變性 :? 元組定義完成后數(shù)據(jù)類型固定, 不能將在同一個(gè)位置指定和定義不同的數(shù)據(jù)類型?
訪問 a.x??
2. 數(shù)組? ?[]? ? 定長(zhǎng)? ?數(shù)組也可以解構(gòu)賦值給變量, 元素必須相同?
? ? 可變性:? ?和元祖相同?
訪問: a[x]
??
3. 函數(shù)? main() 是入口
格式
fn [function_name]([p1],[p2]...)->[return_type]{
return [value] ;
// or end line [value]? ?沒有;? ?
}
注釋: //? ,? /*? */
if- else?
流程控制??
?if [condition]{
?
?}else if[condition]{
?
?}else{
?
?}
可以在? = 右邊? 使用if??
循環(huán) loop,while ,for?
無限循環(huán)
loop{}? ? ?可以使用 break ,continue 打斷?
while[condit]{? ?}
?
for element in []{}
for number in ([start]..[end]) , 左閉右開?
所有權(quán)理解?
棧空間不考慮所有權(quán)問題(可能只是初學(xué),暫時(shí)先這么理解)
堆空間??
一個(gè)蘿卜一個(gè)坑, 蘿卜一旦換坑 前一個(gè)坑就會(huì)被編譯器埋掉??
除非是借用一下的 & , 借用不更改所有權(quán)
或者是clone(), 克隆后變成了倆份。? 類似于c++的深拷貝。
在不使用引用的情況下函數(shù)傳遞參數(shù)會(huì)改變實(shí)參的所有權(quán),
函數(shù)返值也會(huì)將所有權(quán)移交出去
重點(diǎn) :? 可變引用也會(huì)發(fā)生所有權(quán)的移交 而且是一種隱式的移交?
其規(guī)則我猜想是如下的:
fn main() {??
? ? ? let mut a = String::from("stringA");// a 擁有string所在空間的所有權(quán)
? ? ? let b = &mut a;? ?//b 是a的一個(gè)可變引用?
? // 注意: let mut b = &a 和 let b = &mut a 是不一樣的
// 還有 let mut b = &mut a 也是不一樣的
//c++ 表示不虧是我的挑戰(zhàn)者,越來越像我的形狀了【斜眼笑】
? ? ? b.push_str("add"); // 通過引用來修改a空間里的東西?
// 這時(shí)候也會(huì)發(fā)生數(shù)據(jù)競(jìng)爭(zhēng),a 和b都在競(jìng)爭(zhēng)同一塊堆空間
? ? ? //println!("{a}");? ?如果先要訪問a,就會(huì)報(bào)錯(cuò)?
? ? ? println!("");? // 我的理解是 在上一步 內(nèi)存的所有權(quán)會(huì)移動(dòng)給b,也就是可變引用
//在這里,內(nèi)存的所有權(quán)依然在b上 ,但是可以移交給a ,
//當(dāng)然也可以不移交,只是擁有了移交的權(quán)利
? ? ? println!("{a}"); // 移交給 a , b 失去所有權(quán)?
}
用一個(gè)通俗的理解就是 借你的東西(能讓你改的東西),你最少要用(改)一次。
(不用不行,不用沒法還)當(dāng)然也可以不還一直用,但是一旦還了,你就不能用了?
這在某種程度上的確是不會(huì)造成數(shù)據(jù)競(jìng)爭(zhēng) ,而且做法也是比較合乎使用需求的,畢竟
可變引用出現(xiàn) 就是要改值的。改完還給人家也正常。不過就是一旦歸還了所有權(quán)那這個(gè)
可變引用就失效了。
Slice
slice 允許你引用集合中一段連續(xù)的元素序列,?
而不用引用整個(gè)集合。slice 是一類引用,所以它沒有所有權(quán)。
切片和引用的所有權(quán)轉(zhuǎn)移上面不太一樣。
?let mut s = String::from("hello world !");
? ? ? let mut s1 = &s[6..]; // 在這里所有權(quán)并沒有直接發(fā)生轉(zhuǎn)移,所有權(quán)還在s
? // s1 = &s[7..] ;? ?如果存在這行 ,則所有權(quán)轉(zhuǎn)移到s1??
? ? ? s.push_str("thiss"); //所有權(quán)在s? 同時(shí)所有權(quán)無法還給s1, 也就是切片。
? ? ? println!("{s}");
??
前面的引用和借用的使用權(quán)似乎理解錯(cuò)了。
引用和切片不會(huì)直接發(fā)生所有權(quán)的轉(zhuǎn)移 。只是會(huì)賦予其轉(zhuǎn)移所有權(quán)的能力。
如果所有權(quán)一旦回歸到原本的變量,則引用合、切片的變量無法訪問該堆空間
結(jié)構(gòu)體
struct [construct name] {
? ? [varibles]:[type],
}
let [name] = [construct name]{
? ?[varibles]:[value]
}
[name].[varibles] = [value] ;?
參數(shù)和結(jié)構(gòu)體字段同名可以簡(jiǎn)寫
fn build_user(email: String, username: String) -> User {
? ? User {
? ? ? ? email: email,
? ? ? ? username: username,
? ? ? ? active: true,
? ? ? ? sign_in_count: 1,
? ? }
}
寫為
fn build_user(email: String, username: String) -> User {
? ? User {
? ? ? ? email,
? ? ? ? username,
? ? ? ? active: true,
? ? ? ? sign_in_count: 1,
? ? }
}
使用結(jié)構(gòu)體操更新語法
?let user2 = User {
? ? ? ? email: String::from("another@example.com"),
? ? ? ? ..user1? // 除了 email 之外,user2 和 user1 完全相同?
? ? };
元組結(jié)構(gòu)體
內(nèi)部元素可以不用命名
如以下這樣
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
fn main() {
? ? let black = Color(0, 0, 0);
? ? let origin = Point(0, 0, 0);
}
類單元結(jié)構(gòu)體(空結(jié)構(gòu)體)空的元組叫單位元組?
struct AlwaysEqual;
fn main() {
? ? let subject = AlwaysEqual;
}
方法
impl Rectangle {
? ? fn area(&self) -> u32 {
? ? ? ? self.width * self.height
? ? }
}
可以有多個(gè)imp 塊
關(guān)聯(lián)函數(shù)
impl Rectangle {
? ? fn square(size: u32) -> Self {
? ? ? ? Self {
? ? ? ? ? ? width: size,
? ? ? ? ? ? height: size,
? ? ? ? }
? ? }
}
枚舉
enum [enum_name]{
?a,
?b,?
}
let [varibles_name] = [enum_name]::[]
package(包) crate(單元包) Module(模塊) path (路徑)
crate 編譯的最小單位?
crate 有倆種形式 二進(jìn)制 和庫?
二進(jìn)制? -> exe? 必須有 main
庫? ? ? ?-> lib? 沒有main?
?crate root crate root 是一個(gè)源文件,
?Rust 編譯器以它為起始點(diǎn),并構(gòu)成你的 crate 的根模塊
?
包中可以包含至多一個(gè)庫 crate(library crate)。
包中可以包含任意多個(gè)二進(jìn)制 crate(binary crate),
但是必須至少包含一個(gè) crate(無論是庫的還是二進(jìn)制的)。
src/main.rs 和 src/lib.rs 叫做 crate 根
盡量使用絕對(duì)路徑?
Rust 中默認(rèn)所有項(xiàng)(函數(shù)、方法、結(jié)構(gòu)體、枚舉、模塊和常量)都是私有的。
父模塊中的項(xiàng)不能使用子模塊中的私有項(xiàng),
但是子模塊中的項(xiàng)可以使用他們父模塊中的項(xiàng)。
在同一級(jí) 上(兄弟模塊) 可以不使用public 屬性互相直接使用?
super 開頭來構(gòu)建從父模塊開始的相對(duì)路徑