Rustでの文字列を扱う関数周りの雑な理解
関数は、こんな感じシグネチャになることが多い
fn f(s: &str) -> String
多いというだけであって、そうじゃないことももちろんある
&strは、文字列のsliceであり、参照であり、なので同じ
新しいデータを返すため
操作後の文字列は新しいデータであるため、新たにStringを作る
Stringは所有権を持つため安全
関数からStringを返すと、呼び出し元がそのデータの所有権を得る
これにより、関数が返したデータの寿命を心配せずに使える
どういう風に操作するか
GPT-4.icon
3. 性能に注意:
文字列の操作はコピーや再割り当てが発生する可能性があるため、必要に応じて効率的な方法を選択します。
例1: 文字列の奇数部分だけを抜き出す
code:rs
fn extract_odd_indices(input: &str) -> String {
input
.chars() // 文字列を文字単位でイテレーション
.enumerate() // 文字とそのインデックスを取得
.filter(|(i, _)| i % 2 == 1) // 奇数インデックスだけを選択
.map(|(_, c)| c) // 文字だけを取り出す
.collect() // 新しい文字列を作成
}
fn main() {
let original = "abcdefg";
let result = extract_odd_indices(original);
println!("{}", result); // 出力: "bdf"
}
解説:
chars()は文字列を文字に分解します。
enumerate()でインデックスを付与。
filterで条件を適用。
collect()で新しいStringを作成。
---
例2: 文字列の間に-を挟む
code:rs
fn join_with_hyphen(input: &str) -> String {
input
.chars() // 文字列を文字単位でイテレーション
.map(|c| c.to_string()) // それぞれの文字をStringに変換
.collect::<Vec<_>>() // Vec<String>に収集
.join("-") // Vecの要素をハイフンで結合
}
fn main() {
let original = "abcdef";
let result = join_with_hyphen(original);
println!("{}", result); // 出力: "a-b-c-d-e-f"
}
解説:
RustのVecにはjoinメソッドがあります。
charsをto_stringで一度文字列に変換してVecに変換。
joinで間に"-"を挟むよう指定。
---
Haskellとの違い
Haskellのmapやfilterに相当するものはRustのiter()やchars()に続けて使えるイテレーター操作です。
Rustでは明示的な型変換やメモリ所有権の移動を意識する必要があります。
collect()やjoinを活用して、文字列を組み立てます。
---
まとめ
Rustではイテレーターの操作を駆使することで、文字列を効率的に処理できます。Haskellに近い形で連結を繰り返すのではなく、Vecやcollectを使って中間結果を効率的に扱いましょう。また、所有権やコピーコストに注意しつつ、適切な型を選ぶのがRustでの良い習慣です。