私たちは、Rust を使用してポーランド記法のシンプルなコンソールプログラムを作成します。このプログラムは、浮動小数点数と負数をサポートします。
コンソール入力の取得#
Rust では、コンソール入力を取得するのは非常に簡単です。標準ライブラリのenv
には、コンソール入力を簡単に取得するための方法が用意されています。
let symbol:String = env::args()
//入力の何番目か
.nth(1)
// 簡単なエラーハンドリング
.expect("入力が不完全です");
let var_a:String = env::args().nth(2).expect("入力が不完全です");
let var_b:String = env::args().nth(3).expect("入力が不完全です");
println!("|{}|{}|{}|", symbol, var_a, var_b);
それでは、実行してみましょう
cargo run -- 1 2 3
問題がなければ、コンソールに次のような出力が表示されます
|1|2|3|
この時点でのコードは以下の通りです:
use std::env;
// 基本的なコンソール入力の取得
fn obtain_var() {
// 取得したい値
let symbol:String = env::args().nth(1).expect("入力が不完全です");
let var_a:String = env::args().nth(2).expect("入力が不完全です");
let var_b:String = env::args().nth(3).expect("入力が不完全です");
println!("|{}|{}|{}|", symbol, var_a, var_b);
}
fn main() {
obtain_var();
}
しかし、これだけでは不十分です。取得したデータを計算モジュールに渡す必要がありますが、その際には型変換が必要です。
型変換#
コンソールアプリケーションがある程度使いやすいようにするために、小数点数と負数をサポートしています。数値型をf64
(浮動小数点数)に変換する必要があります。
// 型変換
fn change_type(var:String) -> f64 {
let var:f64 = match var.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("エラー:無効な入力");
// エラーの場合は0.0を返す
return 0.0;
}
};
// 変換後の値を返す
var
}
次に、変換した型を保存する方法を見つける必要があります。私はここで配列
を使用して保存することにしました。
現在のコードは以下の通りです:
// コンソール入力の取得
fn obtain_var() {
// 取得したい値
let symbol:String = env::args().nth(1).expect("入力が不完全です");
let var_a:String = env::args().nth(2).expect("入力が不完全です");
let var_b:String = env::args().nth(3).expect("入力が不完全です");
// 変換した値を配列に保存して管理しやすくする
let number_var:[f64; 2] = [change_type(var_a), change_type(var_b)];
...
また、取得した値を保存する方法が必要です。私はここで構造体を使用することにしました:
まず、プログラムの先頭で構造体を宣言します。
...
// データを保存するための構造体の使用
struct ComputeData {
symbol:String,
var_a:f64,
var_b:f64
}
...
次に、この関数が構造体を返すように設定します。
また、値を返すための構造体を作成します。
// コンソール入力の取得
fn obtain_var() -> ComputeData {
// 取得したい値
let symbol:String = env::args().nth(1).expect("入力が不完全です");
let var_a:String = env::args().nth(2).expect("入力が不完全です");
let var_b:String = env::args().nth(3).expect("入力が不完全です");
// 変換した値を配列に保存して管理しやすくする
let number_var:[f64; 2] = [change_type(var_a), change_type(var_b)];
// データを構造体に保存する
let data = ComputeData {
symbol:String::from(symbol),
var_a:number_var[0],
var_b:number_var[1]
};
// 関数は構造体を返す
data
}
さて、次に計算関数を書くことができます。
計算#
入力されたデータと結果を返す関数です。
// 計算
fn compute(symbol:String, var_a:f64, var_b:f64) -> f64
理論的には、match
を使用して値を判断し、結果を返すだけですが、Rust では、match
は直接String
型をチェックすることはできません。したがって、&str
型に変換する必要があります。
完全なコード:
// 計算
fn compute(symbol:String, var_a:f64, var_b:f64) -> f64 {
// スライスの参照モードを使用して、symbolを`&str`に変換する
let symbol:&str = &symbol.to_string()[..];
match symbol {
"+" => var_a + var_b,
"-" => var_a - var_b,
"*" => var_a * var_b,
"/" => var_a / var_b,
// エラーハンドリング
_ => {
println!("無効な計算記号");
// エラーの場合は`0.0`を返す
0.0
}
}
}
完了!#
次に、main
関数を書くだけです~
// 可読性を向上させました
fn main() {
println!("{}",compute(
obtain_var().symbol,
obtain_var().var_a,
obtain_var().var_b
)
);
}
実行#
cargo run -- 演算子 数字1 数字2
例:
cargo run -- / 2 5
ターミナルで実行結果が表示され、結果が返されます -> 0.4
完全なコード#
use std::env;
// データを構造体に保存する
struct ComputeData {
symbol:String,
var_a:f64,
var_b:f64
}
fn main() {
println!("{}",compute(
obtain_var().symbol,
obtain_var().var_a,
obtain_var().var_b
)
);
}
// コンソール入力の取得
fn obtain_var() -> ComputeData {
// 取得したい値
let symbol:String = env::args().nth(1).expect("入力が不完全です");
let var_a:String = env::args().nth(2).expect("入力が不完全です");
let var_b:String = env::args().nth(3).expect("入力が不完全です");
// 変換した値を配列に保存して管理しやすくする
let number_var:[f64; 2] = [change_type(var_a), change_type(var_b)];
// データを構造体に保存する
let data = ComputeData {
symbol:String::from(symbol),
var_a:number_var[0],
var_b:number_var[1]
};
// 関数は構造体を返す
data
}
// 型変換
fn change_type(var:String) -> f64 {
let var:f64 = match var.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("エラー:無効な入力");
// エラーの場合は0.0を返す
return 0.0;
}
};
// 変換後の値を返す
var
}
// 計算
fn compute(symbol:String, var_a:f64, var_b:f64) -> f64 {
// スライスの参照モードを使用して、symbolを`&str`に変換する
let symbol:&str = &symbol.to_string()[..];
match symbol {
"+" => var_a + var_b,
"-" => var_a - var_b,
"*" => var_a * var_b,
"/" => var_a / var_b,
// エラーハンドリング
_ => {
println!("無効な計算記号");
// エラーの場合は`0.0`を返す
0.0
}
}
}
これは、私が Rust を学んでから作成した最初の例です()