「TAURI」と「Rust」の「Option型」と「Result型」を使いこなそう
TAURIのOption型とResult型
以降ではRustとほぼ同じようなことをしますが、TAURIのバックエンドのRustでOption型とResult型をコーディングします。この連載のテーマの1つがTAURIなので、TAURIでのOption型とResult型のサンプルもここで解説します。
TAURIのテンプレートを書き換えて、名前を入力したら"Hello, 名前! You've been greeted from Rust!"と表示し、名前が空の場合は名前のところを"Anonymous"に変えて表示します。
TAURIプロジェクトの作成
第2回のTAURIの設定が済んでいる前提で話を進めていきます。適当なフォルダをカレントディレクトリにして、次のコマンドを実行して「tauri_option_result」などという名前でプロジェクトを新規作成します。それから作成した「tauri_option_result」フォルダをカレントディレクトリにします。
・Tauriプロジェクトの作成コマンド$ cargo create-tauri-app tauri_option_result
TAURIでのOption型
基本的にTAURIのバックエンドもRustそのものなので、Option型の使い方は前述と同じ要領です。例えばサンプルコードを「unwrap_or」メソッドを使わずに「match」文で場合分けするなど改造してみてください。
次のサンプルコードはTAURIのテンプレートの「src-tauri」→「src」→「main.rs」ファイルを書き換えたものです。このサンプルコードをコーディングして「$ cargo-tauri dev」コマンドでTAURIを実行します。
・Option型のサンプルコード#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] //Option型を返す関数 fn get_name(name: &str) -> Option<&str> { if name != "" { Some(name) } else { None } } //TAURIコマンド関数 #[tauri::command] fn greet(name: &str) -> String { let n = get_name(name).unwrap_or("Anonymous"); format!("Hello, {}! You've been greeted from Rust!", n) } //メイン関数 fn main() { tauri::Builder::default() .invoke_handler(tauri::generate_handler![greet]) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
【サンプルコードの解説】
「get_name」関数で名前が空でない場合は「name」引数を「Some」でラップしてOption型を返し、名前が空の場合は「None」をラップしてOption型を返します。
TAURIコマンド「greet」関数で名前が空でない場合はその名前を使い、空の場合は"Anonymous"文字列を「n」変数に代入し、"Hello, 名前! You've been greeted from Rust!"文字列を返します。
「main」関数でフロントエンドのWebページをデスクトップアプリに構築します。
TAURIでのResult型
TAURIのバックエンドもRustそのものなので、Result型の使い方も前述と同じようなやり方です。例えば、先ほどとは逆にサンプルコードのmatch文をunwrap_orメソッドに書き換えるなど改造してみてください。
それでは、さらに次のサンプルコードのように「src-tauri」→「src」→「main.rs」ファイルをコーディングしてTAURIを実行します。実行結果は先ほどのOption型のサンプルアプリと全く同じ動作をします。
・Result型のサンプルコード#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] //Result型を返す関数 fn get_name(name: &str) -> Result<&str,&str> { if name != "" { Ok(name) } else { Err("Anonymous") } } //TAURIコマンド関数 #[tauri::command] fn greet(name: &str) -> String { let n = get_name(name); match n { Ok(s) => { format!("Hello, {}! You've been greeted from Rust!", s) } Err(err) => { format!("Hello, {}! You've been greeted from Rust!", err) } } } //メイン関数 fn main() { tauri::Builder::default() .invoke_handler(tauri::generate_handler![greet]) .run(tauri::generate_context!()) .expect("error while running tauri application"); }
【サンプルコードの解説】
get_name関数で名前が空でない場合はname引数を「Ok」でラップしてResult型を返し、名前が空の場合は「err」引数を「Err」でラップしてResult型を返します。
TAURIコマンドgreet関数で名前が空でない場合は"Hello, 名前! You've been greeted from Rust!"文字列を返し、名前が空の場合は"Hello, Anonymous! You've been greeted from Rust!"文字列を返します。
「main」関数でフロントエンドのWebページをデスクトップアプリに構築します。
ここで紹介したサンプルは簡単なことですがちょっとしたTAURIの練習にもなると思います。少数精鋭で少ないアプリをとことん作り込むなら何度もプロジェクトを新規作成する必要はありませんが、「質より量」なら何度もプロジェクトを作ることもあるでしょう。
筆者は細かく数えて平均すると1ヶ月に2個コンテンツを作り、年間24個、30年で720個もコンテンツを作ってきた計算になります。本当は量より質で行きたいところですが。
3Dオブジェクトを作成したり編集したりする作業を「モデリング」と言い、そのツールを「ポリゴンモデラー」と言います。筆者も3Dツールプログラミングが1番得意なのですが、大学時代のサークルの後輩がサークル時代から「Metasequoia(メタセコイア)」というポリゴンモデラーだけを作り続けていて、「量より質で羨ましいな」と憧れます(後輩は法人化してからは受注の仕事もしているようです)。
おわりに
今回は、Rustの独特で重要な型であるOption型とResult型を解説しました。Option型は値があるかNULLかどうかのRust版で、Result型は例外処理のRust版です。おまけでTAURIでのOption型とResult型の実装例も解説しました。