2026年8月1日 星期六

Rust 程式語言使用筆記

 Rust

說明文件:
https://rust-lang.tw/book-tw/ch01-01-installation.html

Windows 可到這安裝:
https://rust-lang.org/tools/install/

安裝後,可再自行設定客制的環境變數:

RUSTUP_HOME :預設是   C:\Users\{userName}\.rustup,存放 Rustup 的 metadata 和 toolchains

CARGO_HOME :預設是  C:\Users\{userName}\.cargo,是 Cargo home,Cargo, rustc, rustup 及一些其他 command 會放在這 %CARGO_HOME%\bin

IDE 可以用 Visual Studio Code + rust-analyzer plugin

-----------------------------------------------------------------------------

Rust 生態:

rustup : 是一個用來負責安裝及管理 Rust 的工具
Cargo :是一個 Rust 的建構系統與套件管理工具
Crates.io : 是個讓 Rust 生態系統中的每個人都能發佈它們的開源 Rust 專案並讓其他人使用的地方 (類似 Java 的 Maven、Node.js 的 npm)

---------------- rustup 相關 --------------------------------------------------------------

#更新 Rust 版本
rustup update

#移除 Rust 及 rustup
rustup self uninstall

---------------- Rust 相關 --------------------------------------------------------------

#查看 Rust 版本
rustc --version

#編譯並建立執行檔 (如果在 Windows 中執行檔會是 .exe 檔)
rustc <filename>.rs

---------------- Cargo 相關 --------------------------------------------------------------

#查看 Cargo 版本
cargo --version

#建立 Cargo 專案
cargo new <專案名稱>

#編譯建立執行檔
#預設是 debug build,會將建立的執行檔 () 放至 <project folder>/target/debug/ 中
cargo build
#如果是要產生正式發佈用的執行檔,可以指定 --release,Cargo 會在編譯時最佳化編譯結果,產生的執行檔會放在 <project folder>/target/release 而不是 debug 資料夾 
cargo build --release

#編譯並執行專案執行檔 (也可自己用 command line 手動執行,只是要自己指定執行檔位置),如果程式碼沒有改變,cargo run 不會重新執行 build
cargo run

#檢查程式碼,可用來確保程式碼會不會通過編譯,但不會產生執行檔
cargo check

#加入要依賴的 Crates
cargo add <crates名稱>[@<版本號>]
#範例:
cargo add rand
cargo add rand@0.8.5

 #建構所有本地端依賴函式庫的技術文件,並在你的瀏覽器中開啟
cargo doc --open

------------ 語法特色 -------------------

# 變數的 shadowing
# 變數可以遮蔽上一個同名變數,直到離開作用域,例:

fn main() {
    let number = "123";
    // u32 型別的 number 遮蔽(shadow) 了 &str 的 number
    let number: u32 = number.parse()
                            .expect("不是個數字");

    println!("這是個 {number}"); // 這是個 123
}

# tuple
# tuple 可存放多個不同型別的變數,例:

//tuple 例子
//也可以不特別寫出型別宣告 : (u32, &str, f64)
let tuple: (u32, &str, f64) = (3, "abc", 1.2);
println!("{}", tuple.1); // abc
let (_x, _y, z) = tuple;
println!("{z}") // 1.2

# statement (陳述式) 和 expression (表達式),參考
#statement: 不會回傳值。
#expression :會回傳值,不用分號結尾。
#例 :
let x = 1 + 3; 是個 statement,其中 1 + 3 是個 expression
let x = {
    let y = 1 + 3;
    y
}
其中 y 是 expression,會回傳 y 的值給 x

# function 的定義、回傳值方式
# 用 fn 定義 function,用 -> 定前回傳型別
# 可以用 return xxx; 的 statement 提前回傳值,
# 或是在最後一行用 expression 表示回傳 

fn main() {
    println!("{}", add(1, 5)); // 6
    println!("{}", add(0, 0)); // 0
}

fn add(x:u32, y:u32) -> u32 {
    if x == 0 && y == 0 {
        //此為用 statement 回傳值
        return 0;
    }

    //此為用 expression 回傳值
    x + y
}

#enumeration
#可用 match 處理 enumeration 的各變體 (variants)

use std::cmp::Ordering;

fn main() {
    let x = 1;
    let y = 2;
    //使用 match 處理 cmp() 回傳的 enumeration
    match x.cmp(&y) {
        Ordering::Less => println!("less"),
        Ordering::Equal => print!("equal"),
        Ordering::Greater => print!("greater")
    };

    //處理 enumeration 並回傳值的例子
    let number = "123abc";
    let number: u32 = match number
                           .parse() {
        Ok(num) => num,
        Err(_) => {
            println!("無法轉成數字");
            0
        }
    };
    println!("{number}");          
}

TiddlyWiki 筆記

------------------- Macro 相關 ------------------
#Macro 呼叫

#簡寫,但 param 只能用純文字,無法使用 text reference 或 transclude
<<my-procedure param="This is the parameter value">>

#完整寫法 參考
<$transclude $variable="macroName" parameterName="parameterValue"/>
#範例,以 list-tagged-draggable Macro 為例:
 <$transclude $variable="list-tagged-draggable" tag={{!!title}}/>

------------------- Filter 相關 ------------------
參考
#使用方式
#多個 step 可用 +, - 連接
#step 的使用方式
# 純文字可用 [parameter]
[operator:suffix[parameter]] 
#範例:
[tag[xxxTag]]

# text reference 可用 {text reference}
[operator:suffix{text reference}]
#範例:
[tag{!!title}]

# variable 可用 <variable>
[operator:suffix<variable>
#範例:
[tag<currentTiddler>]

------------------- 實作範例筆記 ------------------
# 在 Tiddler 中建立名為 task-end-date 的 field,用 datetime format: YYYYMMDDhhmmss 儲存,
然後再用 $list widget 將這些 Tiddler 以 task-end-date field 由新到舊排序。
#雖然 sort filter 是把 task-end-date 當成文字來排,但 datetime format 被當成文字排也符合照日期排序

<$list filter="[tag{!!title}sort[task-end-date]reverse[]]">
   <div style="margin-bottom:6px;">
      <span style="color:#888;">
        <$view field="task-end-date" format="date" template="YYYY-0MM-0DD"/>
      </span>
      &nbsp;
      <$link to=<<currentTiddler>>/>
   </div>
</$list>