Returns a reference to data owned by the current function

fn main() {
    pub trait Func1tr {
        fn gets(a: &str) -> &str;
    }
    pub struct Func;
    impl Func1tr for Func {
        fn gets(a: &str) -> &str {
            let mut m = String::from("aa");
            m.push_str(a);
            let c = m.as_str();
            return c
        }
    }

    // function_adapter(3);
    // println!("{}",l)
    let m = "sdsd";
    let c = Func::gets(m);
    println!("{}", c);
}   

returns a value referencing data owned by the current function

what do i need to do ? this code will run?

The way you have done it, it is plainly impossible. &str is only a reference and needs to have its data stored elsewhere. But the data it is referencing is dropped at the end of the function and so cannot be referenced later.
You have two options:

  • Change the trait to return a String instead of &str.
  • Change the struct to store the string and return a reference to it. This is not possible since the trait functions doesn't take &mut self.
  • Change the struct to store the string and return a reference to it

how to achieve this one?

I have edited my above reply. Please look at it.

Here's one way if you change the trait too.

Note that @RedDocMD's first solution is almost certainly what you should use here. You want to return a string from gets, and (at least in some cases) it seems you need that string to be dynamically allocated, so the right signature is fn(&str) -> String.

1 Like

&str and Box<str> are the same type with identical representation in memory, returning data "by reference", but they differ by ownership. String is a Box<str> that can grow.

Returning temporarily borrowed &str means you haven't created it, and you're only giving a permission to view data that has already existed before your function was called.

But if you're creating something new, and it has to be stored somewhere. Your function has no place to store it (every local variable will be destroyed), so the only thing you can do is to pass ownership of the data to the caller, so that the caller stores it somewhere.

So you have to return an owning type, not a temporary loan.

If you sometimes allocate a new object, sometimes borrow an existing one, then Cow<str> can efficiently choose between the two.

3 Likes

so how do I use " Cow<str>" in this case?
should you give me a example?

Example.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.