文字列 String
や 文字列スライス &str
、Unicode スカラー値 である char
を結合・連結する方法をまとめました。
文字列を結合する
+ 演算子
+
演算子を使用することで、文字列 String
と文字列スライス &str
を結合することができます。
fn main() {
let h: String = "Hello, ".to_string();
let w: &str = "world!";
let message = h + w;
assert_eq!("Hello, world!", message);
}
文字列 String
同士を結合するためには、右辺に参照を渡す必要があります。
fn main() {
let h: String = "Hello, ".to_string();
let w: String = "world!".to_string();
let message = h + &w; // 参照を渡す
assert_eq!("Hello, world!", message);
}
明示的な所有権の示すため、+
演算子は左辺の所有権を取り、新しい String
を返すように設計されています。
format! マクロ
format! を使うことで、文字列や文字を結合することができます。
- 文字列
String
- 文字列スライス
&str
- Unicode スカラー値
char
fn main() {
let h: String = "Hello, ".to_string();
let w: String = "world!".to_string();
let message: String = format!("{}{}", h, w);
assert_eq!("Hello, world!", message);
}
fn main() {
let h: &str = "Hello, ";
let w: &str = "world!";
let message: String = format!("{}{}", h, w);
assert_eq!("Hello, world!", message);
}
fn main() {
let h: String = "Hello, ".to_string();
let w: &str = "world!";
let message: String = format!("{}{}", h, w);
assert_eq!("Hello, world!", message);
}
fn main() {
let h: String = "Hello, ".to_string();
let w: &str = "world";
let e: char = '!';
let message: String = format!("{}{}{}", h, w, e);
assert_eq!("Hello, world!", message);
}
第一引数の format string に直接変数を指定することも可能です。
fn main() {
let h: String = "Hello, ".to_string();
let w: &str = "world";
let e: char = '!';
let message: String = format!("{h}{w}{e}");
assert_eq!("Hello, world!", message);
}
また、単一の文字列に変換される際に to_string()
が使用されます。
そのため、Display
トレイトを実装した struct などを引数に渡すことも可能です。
use std::fmt::{Display, Formatter};
fn main() {
let h: String = "Hello, ".to_string();
let w: Text = Text::new("world"); // ! はない
let message: String = format!("{}{}", h, w);
assert_eq!("Hello, world!", message);
}
struct Text(String);
impl Text {
fn new(s: &str) -> Text {
Self(s.to_string())
}
}
impl Display for Text {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}!", self.0) // ! は to_string() のときに付与する
}
}
concat! マクロ
concat! は任意の数のコンマ区切りのリテラルを受け取り、文字列スライスに連結します。
fn main() {
// レテラルのみを引数に受け付ける
let message: &str = concat!("My name is John Smith", ',', " I am ", 20, " years old.");
assert_eq!("My name is John Smith, I am 20 years old.", message);
}
push_str
push_str は呼び出し元の String
の末尾に引数で渡した文字列スライスを追加することができます。
呼び出し元の String
に変更が加わるため、mut
である必要があります。
fn main() {
let mut h: String = "Hello, ".to_string(); // ミュータブルにする
h.push_str("world");
h.push_str("!");
assert_eq!("Hello, world!", h);
}
文字列 String
同士を結合したい場合は参照を渡しましょう。
fn main() {
let mut h: String = "Hello, ".to_string(); // ミュータブルにする
let w: String = "world".to_string();
h.push_str(&w); // 参照を渡す
h.push_str("!");
assert_eq!("Hello, world!", h);
}
+= 演算子
+=
演算子を使うことで、文字列を結合できます。
fn main() {
let mut h: String = "Hello, ".to_string(); // ミュータブルにする
let w: String = "world".to_string();
h += &w; // 参照を指定
h += "!";
assert_eq!("Hello, world!", h);
}
なお、+=
演算子はpush_str
メソッドと等価です。
/// Implements the `+=` operator for appending to a `String`.
///
/// This has the same behavior as the [`push_str`][String::push_str] method.
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "stringaddassign", since = "1.12.0")]
impl AddAssign<&str> for String {
#[inline]
fn add_assign(&mut self, other: &str) {
self.push_str(other);
}
}
参考:https://doc.rust-lang.org/src/alloc/string.rs.html#2445
push
push は呼び出し元の String
の末尾に引数で渡したUnicode スカラー値 char
を追加することができます。
fn main() {
let mut h: String = "Hello, ".to_string(); // ミュータブルにする
h.push_str("world");
h.push('!'); // シングルクウォートで囲む
assert_eq!("Hello, world!", h);
}
join
配列に文字列が格納されている場合、join で結合することができます。
fn main() {
let vec: Vec<&str> = vec!["Hello", "world!"];
let message = vec.join(", ");
assert_eq!("Hello, world!", message);
}
まとめ
文字列や文字を結合・連結する方法も目的によって使い分ける必要がありますね!
コメント