42
18

More than 1 year has passed since last update.

Rustの文字列を理解する

Posted at

始めに

Rustの文字列型にはString&strがあります。
正直違いがよく分かっておらずStringは可変長、&strは固定長くらいの
イメージしかなかったので、今回内部の仕組みを調べてまとめました。

ベクタやスライスの話が出てくるのでぜひ前回の記事も参考にどうぞ。

String

Stringは標準ライブラリが提供する型です。
実体はバイト列のベクタ(Vec<u8>)なので、追加や削除が可能です。
文字列はヒープに格納されます。

Stringのコピー

Stringをコピーするにはcloneを呼び出します。
するとヒープにある文字列も丸ごとコピーされます。
このように要素も含め全てコピーすることをディープコピーと言います。

let s1: String = String::from("ABC");
let s2: String = s1.clone();

stringcopy.png

&str

&strはプリミティブな型です。
実体はバイト列のスライス(&[u8])です。
&strとなるのはStringのスライスや文字列リテラル等です。
文字列リテラルとはソースコードにべた書きされている文字列のことです。

let s1: String = String::from("Hello World!!"); // これはString
let s2: &str = &s1[1..4]; // Stringのスライスは&str
let s3: &str = "ABC 123"; // 文字列リテラルは&str
let s4: &str = &s3[0..2]; // 文字列リテラルのスライスも&str

文字列リテラル

この文字列リテラルは少し変わった特徴を持っています。
文字列リテラルは静的領域というスタックでもヒープでもない領域に格納されます。
静的領域に格納されるデータには以下のような特徴があります。

  • プログラムの実行開始から終了まで常に存在している

そのため、文字列リテラルの型は厳密には&'static strという表記になります。
'staticはその変数のライフタイム(生存期間)がプログラム実行中の全期間であることを示しています。

なぜ文字列リテラルは&strなのか

文字列リテラルとは静的領域というスタックから離れた場所にあるバイト列です。
そのバイト列を参照するためにスライスのポインタを用いています。
文字列リテラル自体を所有せず参照しているため、型はstrではなく&strとなります。

以下の様な場合のメモリ配置は下図の通りです。

let s: &str = "ABC";

literal.png

&str → String

&strStringに変換するにはString::fromto_stringを使います。
この時、ヒープに文字列リテラルと同じ文字列がコピーされます。
文字列リテラルは常に静的領域に存在し続けます。

let s1: String = String::from("ABC");
let s2: String = "DEF".to_string();

&str2string.png

String → &str

String&strに変換するにはStringの参照やスライスを取得します。
この場合はヒープに文字列がコピーされることはありません。
変数s2s3も同じヒープを参照しています。

let s1: String = String::from("ABCDE");
let s2: &str = &s1;
let s3: &str = &s1[2..4];

string2&str.png

文字列の連結

文字列を連結させるにはString + &strの演算を行います。
左側の変数は文字列が追加されるため必ずStringでなければいけません。
右側の変数は&str(文字列リテラル、Stringの参照やスライス)となります。

let mut s1: String = String::from("ABC");
let s2: String = String::from("DEF");
s1 = s1 + "!?" + &s2;

concat.png

おわりに

やはりRustは低レイヤーの知識がないと理解するのが難しいです。
C/C++のような低水準言語に近い言語だと改めて実感しました。

参考文献

42
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
18