如何将a转换String
为a &str
?更具体地说,我想将其转换为str
带有static
生存期(&'static str
)的。
&'a str
当时的样子如何?
如何将a转换String
为a &str
?更具体地说,我想将其转换为str
带有static
生存期(&'static str
)的。
&'a str
当时的样子如何?
Answers:
已针对Rust 1.0更新
您不能&'static str
从a获取信息,String
因为String
s可能不会在程序的整个生命周期中都存在,这就是&'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强制,它允许使用just&
运算符,并且编译器将*
根据上下文自动插入适当数量的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
转换为a,&'static str
以便从原始String
线程创建的令牌将在所有线程中可用。没有这个,Rust编译器会抱怨我String
的生命期在main函数的末尾结束,这还不够好,因为它没有'static
保证。
crossbeam
和限定范围的线程
从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
如果要在线程之间共享状态,则使用板条箱。
TL; DR:您可以&'static str
从String
本身具有'static
生命周期的a获得。
尽管其他答案是正确且最有用的,但是有一个(不太有用)边缘情况,您实际上可以将a转换String
为a &'static str
:
引用的生存期必须始终短于或等于引用对象的生存期。即,被引用的对象必须比引用的对象寿命更长(或相等)。因为'static
意味着程序的整个生命周期,所以不存在更长的生命周期。但是相等的寿命就足够了。因此,如果aString
的生存期为'static
,则可以从中获取&'static str
参考。
理论上,在发布功能时,使用Rust 1.31可以创建astatic
类型。不幸的是,只有const函数返回一个是目前,它仍然是一个功能门后(所以锈病每晚需要现在)。String
const fn
String
String::new()
因此,以下代码进行了所需的转换(每晚使用)...并且实际上没有实际用途,只是完整地表明在这种情况下是可能的。
#![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
?