參考和借用
上一篇提到的所有權,在變數的所有權更換時,原本的變數所有權也跟著解除。這讓 Rust 在使用變數的時候跟其他程式語言比較起來,就稍微顯得麻煩。
參考不過 Rust 也提供了相對應的機制可以解決這個問題,也就是參考(reference)。直接看下方的範例:
12345678let x = "abc".toString();do_some(&x);println!("{}", x);fn do_some(s: &String) { println!("{}", s);}
在這個例子中,我們建立了一個變數 x,型別是 String,然後也建立了一個函式,參數的型別也是 String。看起來跟上一篇的範例差不多,不過這裡有一些小小的差異。不同之處在於參數以及型別加上了 & 符號,這個符號就是參考,而參考的使用就是讓開發者不必變更所有權就可以使用其變數的值。這時候運行就不會報錯,並且可以成功印出值。
雖然 & 可以讓開發者建立一個指向變數的參考 ...
記憶體管理機制 - 所有權
所有程式語言都有自己的一套管理記憶體的方式,有些語言使用垃圾回收機制(GC),有些則是讓開發者自行分配和釋放記憶體。而 Rust 則是選擇了另一條路,記憶體是由所有權系統管理,並且在編譯期會檢查是否有違反規則,如果有的話,程式就無法編譯。
所有權是 Rust 中非常獨特的概念,因為它讓 Rust 不用像其他語言一樣需要 GC,這樣的作法也讓 Rust 的效能更好。
所有權所有權主要有三個規則:
每個值都有變數作為一個擁有者。
值只有一個擁有者,任何變數都不能共有擁有權。
當擁有者超出作用域時,該值會立刻刪除。
我們直接來看範例:
123let x = "Rust".to_string();let y = x;println!("{}", x);
首先,我們宣告了一個變數 x,並且將 “Rust” 轉成 String 類型,並且將它賦值給 x。
接著,我們宣告了一個變數 y,並且將 x 賦值給 y。
這時候,x 和 y 都是 String 類型,並且都擁有了 “Rust”。
接著,我們將 x 印出來,這時候會發生錯誤,因為 ...
重複的事就讓迴圈來吧
當要處理比較重複的事情時,我們總不可能一直重複寫一樣的程式碼,這時候我們就可以透過一個迴圈來幫我們處理這件事情。而 Rust 中的迴圈主要分為三種,分別是:
loop
while
for
looploop 這個迴圈是一個無限迴圈,也就是說,只要沒有遇到 break 或 return,這個迴圈就會一直執行下去。
一個最簡單的 loop 迴圈如下:
123456fn main() { loop { println!("Hello, world!"); break; // 如果沒有加上 break,這個迴圈就會一直執行下去 }}
但 loop 如果只單純這樣寫的話,好像不太實用。所以我們就可以利用昨天學到的 if...else 加上判斷的條件,來自己決定什麼時候該停止這個迴圈。
如果我們想要用一個迴圈,來處理從 1 數到 10,那麼就可以這樣寫:
12345678910fn main() { let mut count = 1; loop { ...
控制流程 if…else
不知不覺中我們也一起學到了第 10 天,已經達成三分之一了。(ง๑ •̀_•́)ง
今天來介紹的是 Rust 的條件判斷,相信有學過其他程式語言的人應該都知道,條件判斷是用來判斷程式執行的流程,而在 Rust 中,條件判斷的語法跟其他語言也差不多,但還是有一些地方需要了解一下。
if…else在 Rust 中寫 if…else 非常簡單,不需要在條件加上 (),因為在 if 和 { 中的範圍都是代表條件,這也就表示在這範圍內寫的條件必須是 true 或 false,而且在大多數情況下並不需要加入型別。
以下是一個簡單的範例:
123456789101112131415fn main() { let result = print_result(20, 10); println!("{}", result); // ?}fn print_result(x: i32, y: i32) -> char { let msg; if x > y { ms ...
Rust 的字串
前面雖然在 Rust 的基本型別有提到字元,但是由於字串跟字元不太一樣,而且覺得蠻有趣的,所以本篇將會專門介紹字串。
字串常值字串常值的使用方式跟字元常值不一樣的地方在於,是使用 "" 來將文字包起來,看起來就像這樣:
1let msg = "Hello World!";
也就是說 msg 的值就是一個字串常值(string literial),但只要先記住只要用 "" 包起來的就是字串常值就好了,因為接下來還有比較複雜的部分要稍微理解一下。
Rust 的字串是一種編碼成 UTF-8 的 Unicode 數值,並且一共有 6 種型別,但最主要以及最常用的有兩種,分別是:
&str
String
String首先 String 可以經由字串常值加上 to_string() 宣告,或者是使用以下方式宣告:
1let x = String::from("This is a pen!");
字串以我自己的用途來說,比較多用在組合字串上,那這邊來介紹一下幾種作法,讓大家參考一下。
用 + 來組合這應該 ...
Rust 的複合型別
在 Rust 中,有些型別是由其他型別組合而成的,這些型別稱為複合型別,這些複合型別可以讓我們更好的處理資料,讓程式更簡潔。
元組(tuple)元組有固定長度的特性,代表著一但宣告完,之後就無法再增加或刪減。建立元組的方法是用一個 () 將值放入,每個值之間用 , 分隔,不同值不限定相同型別:
1let nums = (1, 4.4, 333);
雖然不一定要加上型別,但以下為加上型別的範例:
1let nums: (u8, f64, i32) = (1, 4.4, 333);
兩種方法可以取出 tuple 的值:
1.1234567fn main() { let nums: (u8, f64, i32) = (1, 4.4, 333); let one = nums.0; let two = nums.1; let three = nums.2; println!("{}, {}, {}", one, two, three);}
2.12345fn ...
Rust 的基本型別
Rust 的型別是非常重要的,因為它可以幫助我們在編譯時期就找出錯誤,而不是在執行時期才發現錯誤。
所以我們要了解一下 Rust 的型別,並且要知道如何使用它,才能夠感受到 Rust 帶來的好處。
Rust 主要有 4 種基本型別:
整數
浮點數
布林
字元
整數整數有兩種變形,分為非帶號(Unsigned)、帶號(Signed):
長度
Unsigned
Signed
8位元
u8
i8
16 位元
i16
u16
32 位元
i32
u32
64 位元
i64
u64
128 位元
i128
u128
系統架構
isize
usize
兩個的差異在在負號的差別,帶號就是帶負號,每一個帶號可以儲存的數字範圍從 -(2n - 1) 到 2n-1 -1 以內的數字,n 是位元,例如 8 位元的 i8 最小到 -128,最大到 127;而非帶號的 u8 最小因為沒有負數,所以就從 0 開始,最大到 255。
比較特別的是 isize 和 usize 是依據使用者程式運行的電腦架構來決定大小,如果在 64 位元架構的電腦上就是 64 位元,以此類推。
...
優雅的寫出函式
函式在 Rust 中非常重要,從我們的第一天開始就已經展示過函式了。而且在 Rust 寫函式的感覺非常簡單俐落,宣告一個函式就可以不用打很多字,超爽的~
那麼就一起來看怎麼寫函式吧!
函式在 Rust 中,至少都會有一個主函式,也就是 main,而要宣告一個函式也非常簡單,只需要用關鍵字 fn 並接上函式的名稱,並且在後面加上 (),這裡可以加上參數或是不加都可以,最後再加上 {} 就宣告了一個函式,就像這樣:
12fn main() {}
在一般程式中當然不會只有一個函式,所以接著來宣告另一個函式。前面有提到 Rust 的命名慣例是使用 snack case,所以要建立一個 do_stuff 的函式就像這樣:
123fn do_stuff() { println!("Hello, world!");}
那麼要怎麼執行 do_stuff() 呢?只需要在 main() 中呼叫即可:
1234567fn main() { do_stuff();}fn do_stuff() { ...
變數的守備範圍 - 作用域
昨天我們介紹完了變數的用法,那麼今天來介紹一下變數的作用域。
作用域作用域,也就是變數的有效範圍。
一般程式語言在宣告變數後,變數都有它的有效區域。可以把他想成把一個球員派上場,他的活動範圍就會在某個區塊。
而 Rust 也不例外,可以看下方的範例,x 這個變數在大括號中都是有效範圍。而在大括號中又建立了一個大括號,並且宣告了一個變數 y,這裡我們給一個註解叫做 y 區塊,比較好辨識,並且要用 println! 把 x 和 y 給印出來。
12345678fn main() { let x = 10; // y 區塊 { let y = 20; println!("x: {}, y: {}", x, y); }}
最終也可以成功印出 x: 10, y: 20 。雖然在 y 區塊中,並沒有宣告 x,但是由於在 main(){} 中這個大括號已經有宣告,而 x 的作用域在整個 main(){} 中都是有效 ...
從基本功開始打起 - 變數
從今天開始會試著跟大家說明 Rust 的基本知識,只要能夠知道這些基本的話,相信就能掌握 Rust 了!應該吧?
宣告變數首先會先從變數開始,在 Rust 宣告變數只要使用關鍵字 let,例如我們要宣告一個變數 count,並且給予值為 20 的話,就可以這樣寫:
123fn main() { let count = 20;}
然後記得後面要加 ;,這邊有一個比較特別的是預設情況下,變數的值是不能再改變的。
型別Rust 是一種強型別的語言,代表要指定變數的型別,然後在編譯時檢查型別是否正確。
那麼為什麼上面的例子沒有寫型別也可以正確編譯呢?
這是因為 Rust 有 type inference,也就是型別推斷的功能。如果能夠判別型別的話,就不需要寫出來。但如果要寫的話,就可以這樣寫:
1let count: i32 = 20;
這一段的意思是,建立一個變數 count,綁定型別為 i32,而賦予的值為 20。關於型別的部分會在之後有完整的篇幅說明。
模式Rust 提供了一種叫做模式 (Patterns) 的宣告變數技巧,使用方法如下:
1let (x, ...