関数の引数としてのスライス
CoddyのRustジャーニー「Logic & Flow」セクションの一部 — レッスン 56/66。
文字列を扱う関数を書く際、String の代わりに &str を引数の型として使用することで、関数がより柔軟で便利になります。
String パラメータを受け取る関数は、所有権のある文字列のみを受け取ることができます。これにより、呼び出し方法が制限されます:
fn print_message(text: String) {
println!("{}", text);
}
// これは動作しますが、所有権を奪います
let my_string = String::from("Hello");
print_message(my_string); // これ以降、my_string は使用できなくなりますしかし、&str を受け取る関数は、String の参照と文字列リテラルの両方を受け取ることができ、より汎用性が高くなります。
fn print_message(text: &str) {
println!("{}", text);
}
// これで、どちらの型でも呼び出すことができます
let my_string = String::from("Hello");
print_message(&my_string); // Stringへの参照を渡す
print_message("World"); // 文字列リテラルを直接渡すこの柔軟性により、呼び出し側にデータの変換や所有権の放棄を強いることなく、関数がより多くの状況で動作するようになります。
チャレンジ
簡単2つの入力を受け取ります。最初の入力はテキストメッセージで、2番目の入力はメッセージに許可される最大長です。文字列スライス(&str)と最大長(usize)をパラメータとして受け取るtruncate_messageという関数を作成してください。メッセージの長さが最大長を超える場合、関数は最大長までのメッセージのスライスを返す必要があります。そうでない場合は、メッセージ全体を返します。その結果を出力してください。
要件:
- 最初の入力(テキストメッセージ)を読み込み、空白をトリミングする
- 2番目の入力(最大長)を読み込み、空白をトリミングする
- 最大長を
usizeにパースする - 2つのパラメータを持つ関数
truncate_messageを定義する:- メッセージのための文字列スライス
&str - 最大長のための
usize
- メッセージのための文字列スライス
- 関数内で、メッセージの長さが最大長より大きいかどうかを確認する
- 大きい場合は、
&message[0..max_len]を使用して、インデックス0から最大長までのメッセージのスライスを返す - そうでない場合は、メッセージ全体を返す
- 入力されたメッセージと最大長を使用して関数を呼び出す
- 返された結果を出力する
入力:
- 1行目: テキストメッセージ (例:
Hello World from Rust) - 2行目: 数値としての最大長 (例:
11)
出力:
- 最大長を超える場合は切り詰められたメッセージ、そうでない場合は完全なメッセージ
チートシート
&strをパラメータの型として使用すると、文字列の参照と文字列リテラルの両方を受け取ることができるため、Stringを使用するよりも関数が柔軟になります。
fn print_message(text: &str) {
println!("{}", text);
}
let my_string = String::from("Hello");
print_message(&my_string); // Stringへの参照を渡す
print_message("World"); // 文字列リテラルを直接渡す特定の長さまでの文字列のスライスを返すには、スライス構文を使用します。
&message[0..max_len]自分で試してみよう
use std::io;
// TODO: ここで truncate_message 関数を定義します
fn main() {
// テキストメッセージを読み込む
let mut message = String::new();
io::stdin().read_line(&mut message).expect("Failed to read line");
let message = message.trim();
// 最大長を読み込む
let mut max_length_input = String::new();
io::stdin().read_line(&mut max_length_input).expect("Failed to read line");
let max_len: usize = max_length_input.trim().parse().expect("Invalid number");
// TODO: truncate_message 関数を呼び出し、結果を保存します
// TODO: 結果をプリントします
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。