RustでString型から&'static str型に変更することはできない
発端
以下のサイトでString型から&str型への変換はlet ss: &str = &s[..];
みたいな感じでできると書いてあったが、なんかおかしくないか?と思ったのが始まり
[Rust] 文字列 String から文字列スライス str へ変換される仕組み
二つの比較コード
例えば、以下のようなコードを考える
fn main() {
let reference_to_nothing = dangle();
println!("{}", reference_to_nothing);
}
fn dangle() -> &'static str {
let s = String::from("hello");
let ss:&str = &s;
ss
}
上記はss
が借用したものとしてエラーになる
error[E0515]: cannot return value referencing local variable `s`
--> prog.rs:9:5
|
8 | let ss:&str = &s;
| -- `s` is borrowed here
9 | ss
| ^^ returns a value referencing data owned by the current function
error: aborting due to previous error
For more information about this error, try `rustc --explain E0515`.
一方で以下はエラーにはならない
fn main() {
let reference_to_nothing = dangle();
println!("{}", reference_to_nothing);
}
fn dangle() -> &'static str {
let s: &str = "hello";
s
}
もし、let ss:&str = &s;
が&strへの変換になるならば、どちらも正常に動作しないとおかしい気がした。
String自体のライフタイムの制約が変換後の&strにも適応されるためstaticにならない。
調べたらstackoverflowで回答があった
How to convert a String into a &'static str
You cannot obtain &'static str from a String because Strings may not live for the entire life of your program, and that's what &'static lifetime means. You can only get a slice parameterized by String own lifetime from it.
&'static str をStringから取得することはできません。これは、Stringがプログラムの存続期間全体にわたって存在しない可能性があるためです。これが、&'static の有効期間の意味です。 String 自身のライフタイムによってパラメーター化されたスライスのみを取得できます。
Stringを&strに変換したものはStringのライフタイムに縛られるということである。
String型はstaticなライフタイムを指定できないので、Stringから&strに変換したものはstaticなライフタイムは持つことは無いことになる。
これが、前のセクションで述べたプログラムがエラーになった原因である。
そのため、let ss:&str = &s;
が&strへの変換というのは間違いではないが、全く同じものになるというわけでは無いらしい。
Discussion