hiro99ma blog

rust: &str と String を分かって使い分けたい

2025/11/03

Rust で固定文字列を使うことがある。
そのとき、"ほにゃほにゃ" と書いて、vscode で波線が出てきたら .to_string() を付けている。
関数の引数にするときは &str を使ってよいかよくわからないので考えずに &String を使っている。

これはよろしくなかろう。

プリミティブ型

&strStringstd 関係だ。
std はクレートで、その中にプリミティブ型がある。
クレートごとにプリミティブ型を実装できるのだろうか? あまりそういう気はしないのだが。
ChatGPT 氏に訊くと、プリミティブ型が定義されているのではなく再エクスポートしているだけだそうだ。 ドキュメントの都合と思っておけばよさそう。

Rust の文字列

str はプリミティブ型の文字列スライス
その借用が &str

固定文字列の "ほにゃほにゃ"&str というガイド表示が出てくる(vscode)のでそうなのだろう。
str 単独では使えなかったと思う。str::from_utf8() のような使い方はあるようだ。

Stringstd::string の一員だ。
str ページの URL が std/primitive.str.html こちらは std/string/struct.String.html なので構造体と思っておけば良いか。
中身 はこれだけだ。

pub struct String {
    vec: Vec<u8>,
}

固定文字列

strの説明 からすると、固定文字列(string literal)を明示的に書くと &'static str とのこと。
ライフタイムがプログラム全体という意味らしい。 プログラムに直接埋め込まれていてずっと有効というだけだろう。

明示的に書かなくても固定文字列であることに変わりは無いので、変数が見えるならプログラム全体でいつでも有効ということになる。

str ではなく &str なのも、貸し借りできないというか、動かすことができない常に借用されたデータとしてしか使用できないという意味なのだと思う。 ただ 'static は「プログラムで固定」の意味が強そうだ。

Deref

String には Deref<Target = str> というものがある。
しかし String::Deref の説明に出てくるコードのどこが参照外しなのだろう。

fn takes_str(s: &str) { }
let s = String::from("Hello");
takes_str(&s);

String から &str のように構造体(スマートポインタ?)を参照で扱うのも Deref なのだろう。
これがあるから &str なのか String なのかだんだんわからなくなってくるのだと思う。

これがないと &str から String にできるのにその逆がないので面倒なことになりそう。。。
と思ったが、.as_str() を呼び出しているだけなのか。

impl ops::Deref for String {
    type Target = str;

    #[inline]
    fn deref(&self) -> &str {
        self.as_str()
    }
}
writer: hiro99ma
tags: Rust言語

 
About me
About me
comment
Comment Form
🏠
Top page
GitHub
GitHub
Twitter
X/Twitter
My page
Homepage