星期日, 12月 17, 2023

Rust - 參數輸入與 Exit Code

初次看到 Rust 的 main function 時

fn main() {
	println!("Hello World");
}

還以為是與 C 一樣可以透過在 main 在加參數來取得參數。但實際上像 Python 一樣需要透過別的 crate 來處理。

底下是一個輸出所有輸入參數的範例

use std::env;

fn main() {
	let args: Vec<String> = env::args().collect();
    
    for arg in args {
    	println!("{}", arg);
    }
}
env::args() 會取得 iterator,因此範例也可以簡單寫成
use std::env;

fn main() {
    for arg in env::args() {
    	println!("{}", arg);
    }
}
而回傳 Exit Code 的部份, C 是在 main function 回傳 int,而 Rust 是回傳有實做 Termination trait 的物件 (實做了 fn report() -> ExitCode) 即可

而在 Terminalion Trait 中,為以下五種型別定義了實做

  • Infallible
  • !
  • ()
  • ExitCode
  • <T: Termination, E: Debug> Termination for Result<T, E>

前兩者我目前不懂,對於後三者來說

一律回傳成功

fn main() -> () {
	// 表示回傳 ExitCode::SUCCESS
}

回傳指定 ExitCode

use std::process::ExitCode;

fn main() -> ExitCode {
    return ExitCode::SUCCESS;
}

若想返回任意值,可以用

use std::process::ExitCode;

fn main() -> ExitCode {
    return ExitCode::from(0);
}

執行成功時,使用 Ok(T) 中的 T 的 report 結果,若是錯誤則輸出 Err(E) 中的 Debug 訊息並回傳 ExitCode::FAILURE

use std::fs::File;

fn main() -> Result<(), std::io::Error> {
   let f = File::open("bar.txt");

   match f {
      Ok(_) => {
         return Ok(());
      },
      Err(e) => {
         return Err(e);
      },
   };
}
這種 Return 執行錯誤會得到 stderr 的輸出
Error: Os { code: 2, kind: NotFound, message: "No such file or directory" }
上一個 code 也可以寫成
use std::fs::File;

fn main() -> Result<(), std::io::Error> {
	let f = File::open("bar.txt")?;
	// ? 若執行結果是 Err, 直接 return 該 Err
	Ok(())
}
若想隨時中止,可以使用 std::process:exit
fn main() {
   std::process::exit(1);
}

沒有留言: