どのようにして変換するかString
に&str
?具体的にはstr
、static
ライフタイム付きの(&'static str
)に変換したいと思います。
&'a str
当時に変換するとどうなりますか?
SendStr
、所有された文字列または静的文字列のいずれかのタイプであることに注意してください。
どのようにして変換するかString
に&str
?具体的にはstr
、static
ライフタイム付きの(&'static str
)に変換したいと思います。
&'a str
当時に変換するとどうなりますか?
SendStr
、所有された文字列または静的文字列のいずれかのタイプであることに注意してください。
回答:
Rust 1.0用に更新
&'static str
から取得することはできません。String
なぜなら、String
sはプログラムの&'static
存続期間全体にわたって存続しない可能性があり、それが存続期間の意味です。String
自分のライフタイムでパラメーター化されたスライスのみを取得できます。
a String
からスライスに移動&'a str
するには、スライス構文を使用できます。
let s: String = "abcdefg".to_owned();
let s_slice: &str = &s[..]; // take a full slice of the string
あるいは、明示的な再借用をString
実装Deref<Target=str>
および実行するという事実を使用できます。
let s_slice: &str = &*s; // s : String
// *s : str (via Deref<Target=str>)
// &*s: &str
さらに簡潔な構文を可能にする別の方法もありますが、これは、コンパイラーが目的のターゲットタイプを判別できる場合にのみ使用できます(関数の引数または明示的に型指定された変数バインディングなど)。これはderef強制と呼ばれ&
、just 演算子の使用を許可し、コンパイラーは*
コンテキストに基づいて適切な量のを自動的に挿入します。
let s_slice: &str = &s; // okay
fn take_name(name: &str) { ... }
take_name(&s); // okay as well
let not_correct = &s; // this will give &String, not &str,
// because the compiler does not know
// that you want a &str
このパターンはString
/に固有のものではないことに注意してください。たとえば、/ および/ from モジュールまたは/ from モジュールなど、を&str
介して接続されているタイプのすべてのペアで使用できます。Deref
CString
CStr
OsString
OsStr
std::ffi
PathBuf
Path
std::path
let s_slice: &str = &s[..];
これを行うことができますlet s_slice: &str = s.as_str();
's' does not live long enough error
ます。
あなたはそれを行うことができますが、それはのメモリString
をリークすることを含みます。これは軽くやるべきではありません。のメモリをリークString
することで、メモリが解放されないことを保証します(したがってリーク)。したがって、内部オブジェクトへの参照は、'static
有効期間があると解釈できます。
fn string_to_static_str(s: String) -> &'static str {
Box::leak(s.into_boxed_str())
}
fn main() {
let mut s = String::new();
std::io::stdin().read_line(&mut s).unwrap();
let s: &'static str = string_to_static_str(s);
}
String
オブジェクトが削除されない限り、メモリは存続することが保証されます。以来mem::forget
、オブジェクトが削除されないことを保証し、我々は含まへの参照があることが保証されてstr
無効になることはありません。したがって、これは'static
参照であると断言できます
String
にa をに強制する必要がある私のRustアプリケーションにとって非常に役立ちました。これがないと、Rustコンパイラーは、メイン関数の最後で終了する存続期間があったと不満を言うでしょう。&'static str
String
String
'static
crossbeam
スレッドを使用してスコープを指定することです
Rustバージョン1.26以降では、コードを使用せずにa String
をに変換できます。&'static str
unsafe
fn string_to_static_str(s: String) -> &'static str {
Box::leak(s.into_boxed_str())
}
これにより、String
インスタンスがボックス化されstr
、即座にリークされます。これにより、文字列が現在占有している可能性のある余分な容量がすべて解放されます。
crossbeam
スレッド間で状態を共有したい場合は、クレートを使用するなど、オブジェクトのリークよりも望ましいソリューションがほとんど常にあることに注意してください。
TL; DR:それ自体が有効期間を持つ&'static str
から取得できます。String
'static
他の答えは正しく、最も有用ですが、実際にはa String
をa に変換できる(それほど有用ではない)エッジケースがあります&'static str
。
参照の存続期間は常に、参照されるオブジェクトの存続期間と同じかそれより短くなければなりません。つまり、参照されるオブジェクトは、参照よりも長く(または等しく長く)生存する必要があります。'static
はプログラムの全寿命を意味するので、より長い寿命は存在しません。しかし、同等の寿命で十分です。したがってString
、の有効期間がの場合、そこから参照を'static
取得できます&'static str
。
static
タイプのの作成はString
、const fn
機能がリリースされたときのRust 1.31で理論的に可能になりました。残念ながら、現在、aを返す唯一のconst関数String
がString::new()
あり、それはまだ機能ゲートの背後にあります(したがって、今のところRust nightlyが必要です)。
したがって、次のコードは望ましい変換(毎晩使用)を実行します...実際、このエッジケースで可能であることを示す完全性を除いて、実際には使用されません。
#![feature(const_string_new)]
static MY_STRING: String = String::new();
fn do_something(_: &'static str) {
// ...
}
fn main() {
do_something(&MY_STRING);
}
'static
ライフタイムは、文字列が割り当て解除されないこと、つまりメモリリークを意味します。なぜ適切なもの&'static str
で&'a str
はなく、なぜ必要なの'a
ですか?