Rust 如何将字符串转换为&';静态str
如何将Rust 如何将字符串转换为&';静态str,rust,Rust,如何将字符串转换为&str?更具体地说,我想将其转换为具有静态寿命(&'static str)的str。更新为Rust 1.0 您无法从字符串中获取&'static str,因为字符串可能不会在程序的整个生命周期内都有效,这就是&'static生命周期的含义。您只能从中获取由Stringown life参数化的切片 要从字符串转到切片和str,可以使用切片语法: let s: String = "abcdefg".to_owned(); let s_slice: &str = &
字符串
转换为&str
?更具体地说,我想将其转换为具有静态寿命(&'static str
)的str
。更新为Rust 1.0
您无法从字符串
中获取&'static str
,因为字符串
可能不会在程序的整个生命周期内都有效,这就是&'static
生命周期的含义。您只能从中获取由String
own life参数化的切片
要从字符串
转到切片和str
,可以使用切片语法:
let s: String = "abcdefg".to_owned();
let s_slice: &str = &s[..]; // take a full slice of the string
或者,您可以使用String
实现Deref
并执行显式重新加载的事实:
let s_slice: &str = &*s; // s : String
// *s : str (via Deref<Target=str>)
// &*s: &str
请注意,此模式对于String
/&str
不是唯一的-您可以将其用于通过Deref
连接的每对类型,例如,使用模块中的CString
/CStr
和OsString
/OsStr
或模块中的PathBuf
/Path
。您可以这样做,但它涉及泄漏字符串的内存。这不是你应该轻易做的事。通过泄漏字符串的内存
,我们保证永远不会释放内存(因此泄漏)。因此,对内部对象的任何引用都可以解释为具有的静态生命周期
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);
}
从Rust版本1.26开始,可以将字符串
转换为&'static str
,而无需使用不安全的
代码:
fn string_to_static_str(s: String) -> &'static str {
Box::leak(s.into_boxed_str())
}
这会将字符串
实例转换为装箱的str
,并立即将其泄漏。这将释放字符串当前可能占用的所有多余容量
请注意,几乎总是有比泄漏对象更可取的解决方案,例如,如果您想在线程之间共享状态,请使用横梁
板条箱。TL;DR:您可以从本身具有静态寿命的字符串中获取&'static str
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);
}
尽管其他答案是正确的,也是最有用的,但有一个(不太有用的)边缘案例,您确实可以将字符串
转换为&'static str
:
引用的生存期必须始终短于或等于被引用对象的生存期。也就是说,被引用对象的寿命必须比引用对象长(或等于引用对象的寿命)。由于静态
意味着程序的整个生命周期,因此不存在更长的生命周期。但同样的寿命就足够了。因此,如果字符串
的生存期为'static
,则可以从中获得&'static str
引用
当const-fn
功能被释放时,创建String
类型的static
理论上已成为可能,Rust 1.31。不幸的是,当前唯一返回字符串的const函数是String::new()
,它仍然位于功能门之后(因此现在需要每晚运行)
因此,下面的代码进行了所需的转换(使用夜间)…实际上没有实际用途,除了完整地显示在这种边缘情况下是可能的
#![功能(常量字符串新)]
静态MY_STRING:STRING=STRING::new();
fn做某事(&'static str){
// ...
}
fn main(){
做点什么(我的字符串);
}
这似乎既不可能也不可取<代码>“静态”
生存期意味着字符串永远不会被释放,即内存泄漏。为什么您需要&'static str
而不是&'a str
来获得一些合适的'a
?那么将其转换为&'a str
会是什么样子呢?通过as_slice
。如果您描述了您试图解决的具体问题以及执行此操作时遇到的问题,则会更容易提供帮助。另外,请注意,一个类型是一个拥有的字符串或一个静态字符串。string
可以保证,只要对象没有被删除,内存就会保持活动状态。由于mem::forget
保证对象永远不会被删除,因此我们保证对包含的str
的引用永远不会无效。因此,我们可以断言它是一个'静态
引用。这对我的Rust应用程序非常有用,它需要将字符串
强制转换为&'static str
,以便从原始字符串
创建的令牌可以在所有线程中使用。如果没有这个,Rust编译器会抱怨我的String
的生命周期结束于主函数的末尾,这还不够好,因为它没有静态
保证。@mmstick:在这种情况下,更好的解决方案是使用横梁
并确定范围threads@ker:应用程序需要字符串在应用程序的整个生命周期中存在,因此我认为这不是更好的解决方案。还有从该字符串生成的令牌,它要求原始字符串具有静态生存期,以便跨线程共享。@mmstick:如果您将整个应用程序放在一个横梁作用域中,并在作用域之外创建字符串,您将得到完全相同的结果。在Rust 1.10中,而不是中,让s_切片:&str=&s[…]代码>您可以简单地这样做:让s_切片:&str=s.as_str()代码>有时,原始字符串不够活跃,比如在匹配{…}块中。这将导致一个's'寿命不够长的错误
。关于如何在&str
、字符串
、和[u8]
和Vec
之间转换,可以找到更一般的答案。