1

I started learning rust and I'm unsure what is the difference between creating variables like this

let mut word = String::new();

and

let mut word = "";

and also what is a variable which has & infront of it, thanks for your help I hope it's not a very stupid question.

paspielka
  • 47
  • 5

1 Answers1

3

There are two different string-like types in Rust.

String is the type of owned strings. If you have a String, you have total ownership over it. You can modify it, append to it, empty it, and, yes, even drop it. You can pass ownership to someone else, you can let someone else borrow it, and so on. If you take a reference to a String, you get a &String (an immutable reference to a String). This type is fairly useless, and most style checkers will warn you about that. On the other hand, the mutable reference of String, denoted &mut String, can be useful since the borrower can append to the string without taking ownership of it.

str is a string slice. It's an unsized type, so it can't be used as a function argument or a structure component without being wrapped in a reference or a Box. Most commonly, you see it in the form &str, which is an immutably-borrowed string slice. Since this is a reference, it's sized and thus can be used in most conventional contexts.

String::new returns, as the name implies, a new owned String. A string literal such as "" has type &'static str, i.e. a borrowed string slice with static lifetime.

You can borrow a String as a &str with as_str, or with the Deref instance for String. The latter will often kick in automatically if you try to call a str method on a String. On the other hand, there's no way to treat a &str as a String, since the former is borrowed and the latter implies ownership, a stronger guarantee. If you want to go the other way, you need to copy the data from the &str into a new String. This can be done in a couple of ways, simply by using different traits.

String::from(my_str)
my_str.to_owned()

Personally, I use String::from on string literals (i.e. String::from("some constant")) and to_owned on variables, but that's by no means a universal rule.

In summary, String is the type of owned strings, and &str is the type of borrowed string slices. String literals in Rust have type &'static str.

Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116
  • Thanks, I kind of understand, but also seem to have a problem I'm trying to iterate trough a vec names nums like this for x in nums.iter(), the problem is my x value is &i32 and I can't compare it to a i32 value. – paspielka Oct 02 '22 at 18:29
  • 1
    Numbers like `i32` are easy because they're `Copy`, which means you can freely copy them. To go from `i32` to `&i32`, put an `&` in front of it. To go from `&i32` to `i32`, put a `*` in front of it. – Silvio Mayolo Oct 02 '22 at 18:30
  • Thanks, that works perfectly, also Is doing that considered a bad practice? Is it okay if I convert i32 to &i32 also is it better to make them both &i32 or i32 – paspielka Oct 02 '22 at 18:34
  • For `Copy` types, strip off references when you can, so go for `i32`. For types that are not `Copy`, like strings or vectors, you'll have to use `&` more often since it's not cheap to copy them. – Silvio Mayolo Oct 02 '22 at 18:37