このサイトより、
fn second_f64_i32(tuple: (f64, i32)) -> i32 {
tuple.1
}
fn second_f32_i32(tuple: (f32, i32)) -> i32 {
tuple.1
}
fn second_bool_i32(tuple: (bool, i32)) -> i32 {
tuple.1
}
これをジェネリクスにより
fn second_any_i32<T>(tuple: (T, i32)) -> i32 {
tuple.1
}
こう表すことができた。
戻り値に関するジェネリクスを考える
引数がT型で受け取れることは分かったが、戻り値はどうなのか
fn getStringInput(message: &str) -> String {
let mut input = String::new();
print!("{}", message);
io::stdout().flush().unwrap();
input.clear();
io::stdin().read_line(&mut input).expect("failed to read line");
return input.trim().to_string();
}
fn getIntInput(message: &str) -> i32 {
let mut input = String::new();
print!("{}", message);
io::stdout().flush().unwrap();
input.clear();
io::stdin().read_line(&mut input).expect("failed to read line");
return input.trim().parse().expect("invalid number");
}
これ、戻り値がの型が違うだけだから、まとめたいね
use std::str::FromStr;
fn get_input<T: FromStr>(message: &str) -> T
where
T::Err: std::fmt::Debug, // `parse()` のエラーメッセージを扱うための制約
{
let mut input = String::new();
print!("{}", message);
io::stdout().flush().unwrap();
io::stdin().read_line(&mut input).expect("Failed to read line");
input.trim().parse().expect("Invalid input")
}
こうしたらできました
ここでwhereで記載されている T::Err: std::fmt::Debug
をトレイト境界といいます。
これは、
fn print<T>(x: T) {
println!("{}", x);
}
このようなプログラムで、i32とか&strは受け取れるけど、タプル型を受け取れないですね
コンパイルエラーになります。
要するに、i32とか&strとタプル型の間に存在するT型として扱える形式の限界をトレイト境界といいます
したがってこのようなプログラムでトレイト境界を指定する必要があり、以下のように記述されます
fn print<T: std::fmt::Display>(x: T) {
println!("{}", x);
}
「 T が std::fmt::Display の条件を満たす」という意味で、この記法以外にもimplや上で使ったようなwhereでの記法があります それは記事の初めのリンクで詳しく書かれています