您正在閱讀「Rust Taiwan 2020 讀書會筆記」的一節,歡迎點擊本頁上方的 協助編修。
.rs
的檔案 ex: main.rs
fn main () {
}
Hello World!
fn main () {
println!("Hello World");
}
rustc main.rs
main
/main.exe
檔,執行 main
/main.exe
檔./main
cargo new hello_world
src/main.rs
的檔案
fn main() {
println!("Hello, world!");
}
cargo check
cargo build
cargo run
cargo build --release
fn main () {} // fn 是 function 的關鍵字
println!("Hello World!") // println 是印出資料的語法,! 是 macro 的寫法, println! 是官方的 macro ,會在編譯時期根據目標平台轉換成相應的程式碼
fn main () {
let x = 5; // 會被自行推定為 i32
let y: i32 = 10; // 也可以宣告變數型別
}
fn main () {
let x = 5;
x = 10; // 不可以改變 x 的值
}
mut
fn main () {
let mut x = 5;
x = 10; // OK
}
fn main () {
let (a, b) = (1, 2);
let (mut x, mut y) = (1, 2); // 或宣告可變的變數
}
fn main () {
let x: i32;
println!("{}", x); // use of possibly-uninitialized `x`
}
fn main () {
let x: i32;
let condition = true;
if condition {
x = 1; // 因為在這裡被初始化了
println!("{}", x); // 所以可以使用
}
// 但在這裡沒有被初始化
println!("{}", x); // 在這裡會出錯
}
底線
帶過,就可以讓編譯器底線
變數也被視為不能被使用的變數,所以不可以在後面的程式碼中使用到
fn main () {
let _ = "hello";
println!("{}", _); // expected expression
}
fn main () {
let x = "Hello";
println!("{}", x);
let x = 5; // 前面的變數會被 shadowing
println!("{}", x);
}
type
為一個型別取新的名字
type Age = u32;
fn grow (age: Age, year: u32) -> Age {
age + year
}
static GLOBAL: i32 = 0;
const GLOBAL: i32 = 0;
let a = [1, 2, 3];
let first = a[0];
let second = a[1];
let a = ("hello", 1)
struct Person {
age: u32,
weight: u32,
}
fn main () {
let ballfish = Person { age: 18, weight: 40 };
println!("{}, {}", age, weight);
}
struct Color (i32, i32, i32);
enum Food {
Noodle,
Rice
}
enum Message {
Quit,
ChangeColor(i32, i32, i32),
Move { x: i32, y: i32 },
}
fn main () {
let x = { println!("喵喵喵喵"); 5 };
println!("{}", x);
}
fn main () {
let n = 4;
if n < 0 {
println!("Wow");
} else if n == 0 {
println!("owo");
} else {
println!("Orz");
}
// Orz
}
fn main () {
let n = 4;
let x = if n < 4 { "owo" } else { "OAO" };
println!("{}", x);
// OAO
}
()
,以剛剛的例子而言,由於 x
必須在編譯時期就確定型態,所以 if/else 回傳的值必須一致。也因此,通常 if 會伴隨 else,除非 if 沒有回傳值
fn main () {
let n = 4;
let x = if n < 4 { "owo" } else { 5 }; // expected `&str`, found integer
println!("{}", x);
}
fn main () {
let n = 4;
let x = if n < 4 { "owo" }; // expected `()`, found `&str`
}
fn main () {
let n = 4;
let x = if n < 5 { println!("OAO") };
// OAO
}
fn main () {
loop {
print!("喵喵喵喵");
}
}
continue
與 break
fn main () {
loop {
print!("汪汪");
break;
}
loop {
print!("喵喵喵喵");
continue;
print!("噗伊");
}
}
break
後面接值,這個值會被作為回傳值
fn main () {
let a = loop {
println!("噗伊");
break 5;
};
println!("{}", a);
// 噗伊
// 5
}
fn main () {
let mut n = 0;
while n < 10 {
println!("喵喵喵喵");
n += 1;
}
}
break
在 while
中不能接值,所以永遠會回傳 ()
fn main () {
let mut n = 0;
let x = while n < 10 {
n += 1;
break 5; // can only break with a value inside `loop` or breakable block
};
}
fn main () {
let mut n = 0;
// OK,但 x = ()
let x = while n < 10 {
n += 1;
break;
};
}
break
在 while
裏面才會不能接值,因為 while 沒有被執行的情況下,回傳直永遠是 ()
,所以在 while block 裡的回傳值一定要是 ()
fn main () {
let x;
loop { x = 1; break; }
println!("{}", x); // x 一定會在 loop 中被初始化,所以編譯會過
}
fn main () {
let x;
while true { x = 1; break; }
// 因為編譯器無法保證 while block 裡的程式碼一定會被執行到,所以無法保證 x 一定會被初始化,因此編譯不會過
println!("{}", x); // use of possibly-uninitialized `x`
}
for (i = 0;i < 10;i++)
,Rust 中的 for loop形式跟其他語言的 for-each 視同義的
fn main () {
let array = [1, 2, 3];
for i in array.iter() {
println!("{}", i);
}
}
for loop 跟 while 的特性一樣,block 中的 break
後不可以接值, for loop 可以接在等號後面
function
fn add (t: (i32, i32)) -> i32 {
t.0 + t.1
}
fn add ((x, y): (i32, i32)) -> i32 {
x + y
}
fn add ((x, y): (i32, i32)) -> i32 {
x + y
}
fn main () {
let func = add;
println!("{}", func((1, 2))); // 3
}
fn amazing () -> ! {
panic!("crash the application~~");
}
const fn add ((x, y): (i32, i32)) -> i32 {
x + y
}
fn main () {
const CONSTANT: i32 = add((1, 2));
println!("{}", CONSTANT);
}