Return local String as a slice (&str)

后端 未结 5 1600
温柔的废话
温柔的废话 2020-11-21 06:27

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 loca

5条回答
  •  一向
    一向 (楼主)
    2020-11-21 07:07

    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.

    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 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();
    

    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.

    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
    }
    

提交回复
热议问题