How come Strings don't need & unlike String literals?

fn main()
    let x: String = String::from("String");
    let y: &str = "Str literal";

    println!("{}, {}", x, y);

If both x and y are references, why does only y require a & symbol just before the str unlike x?

x is not a reference but an owned String value. I'd highly recommend for everyone to read the chapter 4 of the book before writing code, since the borrowing is a unique concept of the Rust.


Hey man.


This is how x looks like. It contains a pointer, length and capacity. It points to the data that is stored on the heap, so how come it is not considered reference if it is just pointing data to the heap data?

Pointers aren't references. References come with additional restrictions and represent a borrow of data owned by something else. String owns the data behind its pointer, so it has control over it and is responsible for deallocating the memory when it goes out of scope.


Makes sense now mate thanks. So references in general ONLY contain the pointer right?

References to sized types just consist of a pointer. References to unsized types also record a length, in the case of str and [T], or a pointer to a method table, in the case of dyn Trait.


I don't think it's totally accurate, but I prefer to think of & as borrowing rather than a reference. I find it helps me reason about things a lot better especially when learning.

String::from("String") returns an owned value, so x's type is just String. String literals are hardcoded into the binary, so y does not own it, but rather just borrows it from the binary and so it's type has the &.


For your question, it doesn't matter how it works internally. You can have a type that literally is a reference internally:

struct Ref<'a, T>(&'a T);

However, Ref itself is not a reference. Its implementation is not exposed in the type system and may change backwards-compatibly. The same goes for String.

Any value has a distinct type, and it can't have two types at the same time. If a value has type String, it cannot have type &_. (Note that some features allow to name the same type in different ways, notably type aliases and default generic parameters).


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.