0

Why does a String in Rust have fixed size and str variable size? The docs characterize a str as:

a pointer to some bytes, and a length

A pointer + length sounds like a fixed size to me.

Herohtar
  • 5,347
  • 4
  • 31
  • 41
Test
  • 962
  • 9
  • 26

1 Answers1

1

A String is just a normal struct, and isn't built into the language, nor does it use any (substantive) compiler magic. Strings are just wrappers around Vec<u8>. A Vec is a pointer to a buffer, along with a size and capacity to keep track of the buffer size. Thus a String has a size of thrice usize on the heap, along with a variable amount of heap storage.

A &str is "a pointer to some bytes, and a length". It's a fat pointer with a fixed size. Notice the ampersand: an &str is different from a str. A str is a dynamically sized type that refers directly to the bytes of a string, without any reference or indirection. For the most part, you can't directly handle strs, since they don't have a fixed size, and so they must be handled behind a reference.

To summarize:

  • That quote refers to &str, which is a fat pointer to some UTF-8 bytes
  • A str refers to some UTF-8 bytes, and usually can't be handled without some indirection
smitop
  • 4,770
  • 2
  • 20
  • 53
  • When s is a String and one runs &s, it somehow turns into a &str. How is this possible? Is `str` not in fact bytes but an abstract type? – Test Mar 20 '22 at 01:19
  • @Test `String` implements `Deref`, so when doing `&s` it can be [automatically dereferenced](https://stackoverflow.com/q/28519997/10113238) to a `str`, of which the reference is taken. The term used to describe `str` is a ["dynamically sized type"](https://doc.rust-lang.org/nomicon/exotic-sizes.html#dynamically-sized-types-dsts). DSTs can't exist without having a reference to them. – smitop Mar 20 '22 at 01:26
  • I see, so &String is "str"? Or is "&String" converted to "&str"? – Test Mar 20 '22 at 04:18
  • 1
    `&String` can be automatically converted to `&str` with this implementation - https://doc.rust-lang.org/stable/alloc/string/struct.String.html#impl-Deref. – Cerberus Mar 20 '22 at 04:35
  • Also note that `&String` is like `&&str` and generally an anti-pattern (`&mut String` is fine, though). – Chayim Friedman Mar 20 '22 at 20:50