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
之间转换,可以找到更一般的答案。