Duncan
Duncan

Reputation: 375

Why can size_of be used on unsized types?

The documentation for std::mem::size_of doesn't provide an example of &str or String being used, but both return sizes with the following code:

println!("The size of a string slice (&str): {}", mem::size_of::<&str>());
// OUTPUT: The size of a string slice (&str): 16
println!("The size of a growable string (String): {}", mem::size_of::<String>());
// OUTPUT: The size of a growable string (String): 24

From my understanding, a &str type is just a reference to the beginning of a "sequence of Unicode scalar values encoded as a stream of UTF-8 bytes". Is &str referring to the size of two pointers? I know a pointer is 8 bytes long on a 64-bit system.

mem::size_of::<str>() does return an error, like I would have expected. However, both String and &String return sizes.

Upvotes: 5

Views: 589

Answers (1)

Shepmaster
Shepmaster

Reputation: 431589

Why can size_of be used on unsized types?

It cannot. If it could, it would be defined as:

pub const fn size_of<T: ?Sized>() -> usize
//                    ^^^^^^^^

Why can size_of be used on [&str / String / &String]?

&str, String, and &String are all sized types.

A &str is essentially:

struct StringSlice {
    ptr: *const u8,
    len: usize,
}

A String is essentially:

struct String {
    ptr: *const u8,
    len: usize,
    cap: usize,
}

A &String is essentially:

struct StringRef {
    ptr: *const String,
}

referring to the size of two pointers

A usize is an integer type that is guaranteed to be the size of a native pointer, so... kind of?

See also:

Upvotes: 5

Related Questions