如何将String
转换为&str
?更具体地说,我想将其转换为str
生命周期为static
(&'static str
)。
答案 0 :(得分:90)
针对Rust 1.0进行了更新
您无法从&'static str
获取String
,因为String
在您的计划的整个生命周期中都不存在,这就是&'static
生命周期的含义。您只能通过String
生命周期获得参数化的切片。
要从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强制,它允许只使用&
运算符,编译器将根据上下文自动插入适当数量的*
:
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
来自std::ffi
模块的} / CStr
和OsString
/ OsStr
或来自std::path
模块的PathBuf
/ Path
。
答案 1 :(得分:20)
你可以这样做,但它涉及泄漏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);
}
答案 2 :(得分:14)
从Rust版本1.26开始,无需使用String
代码就可以将&'static str
转换为unsafe
:
fn string_to_static_str(s: String) -> &'static str {
Box::leak(s.into_boxed_str())
}
这会将String
实例转换为框式str
并立即泄漏它。这样可以释放字符串当前可能占用的所有多余容量。
请注意,几乎总是有比泄漏对象更可取的解决方案,例如如果要在线程之间共享状态,请使用crossbeam
条板箱。
答案 3 :(得分:1)
TL; DR:您可以从&'static str
获得String
,而'static
本身的寿命为String
。
尽管其他答案是正确且最有用的,但是有一个(不是那么有用)边缘情况,您实际上可以将&'static str
转换为'static
:
引用的生存期必须始终短于或等于引用对象的生存期。即被引用的对象必须比引用的对象寿命更长(或相等)。由于String
表示程序的整个生存期,因此不存在更长的生存期。但是相等的寿命就足够了。因此,如果'static
的生存期为&'static str
,则可以从中获得static
引用。
从发布String
功能开始,Rust 1.31可以创建类型为const fn
的{{1}}。不幸的是,当前返回String
的唯一const函数是String::new()
,它仍然位于功能闸的后面(因此,现在需要Rust每晚)。
因此,以下代码进行了所需的转换(每晚使用)...并且实际上没有实际用途,只是完整地表明在这种情况下是可能的。
#![feature(const_string_new)]
static MY_STRING: String = String::new();
fn do_something(_: &'static str) {
// ...
}
fn main() {
do_something(&MY_STRING);
}