首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >`temp_string.as_str()`和`&temp_string`

`temp_string.as_str()`和`&temp_string`
EN

Stack Overflow用户
提问于 2022-02-23 00:44:15
回答 2查看 111关注 0票数 0
代码语言:javascript
复制
fn main() {
    let s = "FOO";
    let s_lower = s.to_lowercase().as_str();

    println!("{}", s_lower);    
}

他说

代码语言:javascript
复制
3 |     let s_lower = s.to_lowercase().as_str();
  |                   ^^^^^^^^^^^^^^^^         - temporary value is freed at the end of this statement

然而,

代码语言:javascript
复制
fn main() {
    let s = "FOO";
    let s_lower = &s.to_lowercase();

    println!("{}", s_lower);    
}

都没问题。

为什么?是因为&temp_string是一个不同于&str&String吗?如果是这样的话,是怎么做的?

谢谢!

EN

回答 2

Stack Overflow用户

发布于 2022-02-23 08:17:54

来自“kmdreko& @sudo”的几个链接是有用的。

我理解为什么s.to_lowercase().to_str()不编译,但不知道为什么&s.to_lowercase()没有同样的问题。这叫做临时寿命延长,医生说:

let语句中表达式的临时作用域有时会扩展到包含let语句的块的作用域。这是在通常的临时作用域太小时,根据某些语法规则进行的。例如:

代码语言:javascript
复制
let x = &mut 0;
// Usually a temporary would be dropped by now, but the temporary for `0` lives
// to the end of the block.
println!("{}", x);

我觉得这个特别的规则有点武断。这是一个关于为什么它不适用于我共鸣的temp.as_bytes()的原因的temp.as_bytes()

令人惊讶的是,有一个RFC似乎想要使这更有规律,但不知何故不适用于这里。

这篇文章解释了为什么在某些情况下需要临时生命周期扩展。

我发现这个旧锈参考文献对于理解临时值也很有帮助,还有很多例子。

票数 1
EN

Stack Overflow用户

发布于 2022-02-23 06:37:17

这里有两点要说明。

  1. 是的,&String&str是不同的类型。前者是对动态堆字符串类型的引用,后者是对字符串部分的引用。我建议回顾一下片上锈蚀书的这个第二章
  2. 如错误消息所示,临时的生存期才是真正的罪魁祸首。

在第一个示例中,to_lowercase()的返回类型是String --它返回将由调用方拥有的String。但是,我们没有将这个返回值绑定到一个变量--我们试图先调用as_str(),然后将其结果绑定到s_lower。如果不首先绑定结果,as_str()就不能与to_lowercase()链接,因为它需要引用调用String,而调用String是不能在临时的情况下完成的。这是有问题的,因为在调用String as_str()之前,to_lowercase()返回的最终会被删除(被释放和不可使用),因为编译器意识到不能使用它。

为了更清楚地说明,他的第一个例子相当于:

代码语言:javascript
复制
fn main() {
    let s = "FOO";
    // temporary scope
    {
        let temporary = s.to_lowercase();
    }
    let s_lower = temporary.as_str();
}

基于临时值规则,这种方法有望使临时值的生存期更加清晰。要修复第一个示例,您必须这样做:

代码语言:javascript
复制
fn main() {
    let s = "FOO";
    let s_lower = &s.to_lowercase();
    let s_lower_slice = s_lower.as_str();
    println!("{s_lower_slice}");
}

这一点在答案@kmdreko链接上图中有进一步的解释。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71230066

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档