0

How is the following made to work (safely)? There are serious downsides to using 'static.

fn whatever() {
    let mut myslice = "goodbye"; //variable that lives, but not necessarily the whole program!
    print!("{}", myslice);
    {
        let mystring = "hello".to_string();
        myslice = &*mystring;
    }
    print!("{}", myslice);
}

The second print should produce 'hello'.

I encounter this problem commonly in lots of forms.

The open bracket could represent multiple things, like calling a function or using an if statement.

E.g.'If there are problems with the value in myslice and things are not working properly. {'

Working out the replacement, (which proved in the above example to be 'hello') is frequently no easy or quick matter, and involves code not to be touched unless it was proved there was a problem. As is normal in Rust, there are many alternatives to &*mystring (&mystring[..], : &str on the left, &*mystring, mystring.as_str(), etc.) but none explicitly manipulate the perfectly available, mutable and live long enough variable as if I had typed let found = "hello".to_string; myslice = &found;' outside the curly brackets. I have tried.clone()` in various places. Why does Rust make such a meal of this simple request? Obviously I am prepared to pay the minuscule processor time to actually do the request.

I would like a general solution. However, it seems the above problem is explicitly with the type 'String'. e.g. let found = "hello"; let myslice = found; seems to work, even inside the brackets. (found is now &str - it does not seemed ever 'borrowed'.) Is the problem directly or indirectly tied up with not knowing length at compile time? Unfortunately and frequently this is not in my control, I have to use what crates decide to give.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Yogi39
  • 1
  • 2
    Is there a reason `myslice` needs to be a slice and not a `String`? Then you'd avoid needing a reference entirely. – loganfsmyth Jun 02 '20 at 17:06
  • 1
    @Shepmaster, I took the liberty of removing one of the duplicates you linked to add [In Rust, what's the difference between “shadowing” and “mutability”?](https://stackoverflow.com/questions/53235334/in-rust-whats-the-difference-between-shadowing-and-mutability) which I believe to be a source of confusion here (there is a 5 links limit). – mcarton Jun 02 '20 at 17:11
  • As loganfsmyth says, making both a `String` is probably the easiest thing for you to do. You could also [use a `Cow`](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=58308af5840fe8478812002412cdedfa) as suggested in one of the duplicates, or [declare `mystring` outside of the block](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=90a64887dfb8acfd6b78341abe3bcaa6) – Shepmaster Jun 02 '20 at 17:14
  • It's also worth reading [What are the differences between Rust's `String` and `str`?](https://stackoverflow.com/q/24158114/155423) – Shepmaster Jun 02 '20 at 17:17
  • There's no general solution because it is not a general problem. If you want to move `mystring` into `myslice`, then that's one problem, but if you want `myslice` to *reference* `mystring`, that's a different problem. There might also be other things you want to do like shared ownership or copy-on-write. There can't be a single solution that works for all of them. What other languages do is mostly just pick one version of the problem to solve, while making the other versions difficult or impossible. Rust lets you decide, which is why you sometimes have to do a little more upfront thinking. – trent Jun 02 '20 at 18:57

0 Answers0