将本地字符串作为切片返回(&str) [英] Return local String as a slice (&str)

查看:48
本文介绍了将本地字符串作为切片返回(&str)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有几个问题似乎与我遇到的相同问题有关.例如,请参阅此处此处.基本上,我试图在本地函数中构建一个 String,然后将它作为 &str 返回.切片不起作用,因为寿命太短.我不能在函数中直接使用 str 因为我需要动态构建它.但是,我也不想返回 String ,因为一旦构建,它所进入的对象的性质就是静态的.有没有办法让我的蛋糕也吃掉?

There are several questions that seem to be about the same problem I'm having. For example see here and here. Basically I'm trying to build a String in a local function, but then return it as a &str. Slicing isn't working because the lifetime is too short. I can't use str directly in the function because I need to build it dynamically. However, I'd also prefer not to return a String since the nature of the object this is going into is static once it's built. Is there a way to have my cake and eat it too?

这是一个最小的非编译复制:

Here's a minimal non-compiling reproduction:

fn return_str<'a>() -> &'a str {
    let mut string = "".to_string();

    for i in 0..10 {
        string.push_str("ACTG");
    }

    &string[..]
}

推荐答案

不,你不能这样做.为什么会这样,至少有两种解释.

No, you cannot do it. There are at least two explanations why it is so.

首先,记住引用是借用的,即它们指向一些数据但不拥有它,它是由其他人拥有的.在这种特殊情况下,字符串(您要返回的切片)归函数所有,因为它存储在局部变量中.

First, remember that references are borrowed, i.e. they point to some data but do not own it, it is owned by someone else. In this particular case the string, a slice to which you want to return, is owned by the function because it is stored in a local variable.

当函数退出时,它的所有局部变量都被销毁;这涉及调用析构函数,String 的析构函数释放字符串使用的内存.但是,您希望返回指向为该字符串分配的数据的借用引用.这意味着返回的引用立即变为悬空——它指向无效内存!

When the function exits, all its local variables are destroyed; this involves calling destructors, and the destructor of String frees the memory used by the string. However, you want to return a borrowed reference pointing to the data allocated for that string. It means that the returned reference immediately becomes dangling - it points to invalid memory!

Rust 的诞生就是为了防止此类问题.因此,在 Rust 中,不可能返回指向函数局部变量的引用,这在 C 等语言中是可能的.

Rust was created, among everything else, to prevent such problems. Therefore, in Rust it is impossible to return a reference pointing into local variables of the function, which is possible in languages like C.

还有一种解释,稍微正式一些.让我们看看你的函数签名:

There is also another explanation, slightly more formal. Let's look at your function signature:

fn return_str<'a>() -> &'a str

请记住,生命周期和通用参数是参数:它们由函数的调用者设置.例如,其他一些函数可能会像这样调用它:

Remember that lifetime and generic parameters are, well, parameters: they are set by the caller of the function. For example, some other function may call it like this:

let s: &'static str = return_str();

这要求 'a'static,但这当然是不可能的 - 你的函数不返回对静态内存的引用,它返回一个引用更短的寿命.因此这样的函数定义是不合理的,被编译器禁止.

This requires 'a to be 'static, but it is of course impossible - your function does not return a reference to a static memory, it returns a reference with a strictly lesser lifetime. Thus such function definition is unsound and is prohibited by the compiler.

无论如何,在这种情况下,您需要返回一个拥有类型的值,在这种特殊情况下,它将是一个拥有的String:

Anyway, in such situations you need to return a value of an owned type, in this particular case it will be an owned String:

fn return_str() -> String {
    let mut string = String::new();

    for _ in 0..10 {
        string.push_str("ACTG");
    }

    string
}

这篇关于将本地字符串作为切片返回(&amp;str)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆