어떻게 변환 할 String
에 &str
? 보다 구체적으로는, 내가로 변환하고 싶은 str
와 static
수명 ( &'static str
).
&'a str
그때 로 변환하는 것은 어떻게 보 일까요?
SendStr
소유 된 문자열 또는 정적 문자열 인 유형에 유의하십시오 .
어떻게 변환 할 String
에 &str
? 보다 구체적으로는, 내가로 변환하고 싶은 str
와 static
수명 ( &'static str
).
&'a str
그때 로 변환하는 것은 어떻게 보 일까요?
SendStr
소유 된 문자열 또는 정적 문자열 인 유형에 유의하십시오 .
답변:
Rust 1.0 업데이트
s는 프로그램의 전체 수명 동안 살 수 없기 때문에 &'static str
a에서 얻을 수 없습니다 . 그것이 평생의 의미입니다. 자신의 수명에 따라 매개 변수화 된 슬라이스 만 가져올 수 있습니다 .String
String
&'static
String
String
a에서 슬라이스 로 이동하려면 &'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 coercion 이라고하며 &
연산자 만 사용할 수 있으며 컴파일러는 *
컨텍스트에 따라 적절한 양의 s를 자동으로 삽입합니다 .
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
/에 대해 고유하지 않습니다. 예를 들어 / 및 / 에서 모듈 또는 / 에서 모듈을 &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
에 &'static str
원본에서 만든 토큰 있도록 String
모든 스레드에서 사용할 수있을 것이다. 이것이 없으면 Rust 컴파일러는 내 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 : 당신은 그 자체가 평생을 가지고있는 a &'static str
로부터 얻을 수 있습니다 .String
'static
다른 답변이 정확하고 가장 유용하지만 실제로 a String
를 a 로 변환 할 수있는 (그다지 유용하지 않은) 엣지 케이스가 있습니다 &'static str
.
참조의 수명은 항상 참조 된 개체의 수명보다 짧거나 같아야합니다. 즉, 참조 된 객체는 참조보다 오래 (또는 동일하게) 살아야합니다. 'static
프로그램의 전체 수명을 의미 하므로 더 긴 수명은 존재하지 않습니다. 그러나 동등한 수명이면 충분합니다. 따라서 String
a의 수명이 '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