Str::as_bytes (again)

I'm a bit confused about what's really going on in str::as_bytes. According to the API docs the string slice is "converted". According to some earlier responses to a similar question both Str and ByteSlice have exactly the same structure (a raw ptr to bytes plus a usize len field), but some people say that str::as_bytes, using mem::transmute, "copies" the bytes. But is any copying going on? When I look at the assembly code in https://godbolt.org, the asm code shows that as_bytes is basically a noop. So, is it correct to say that str::as_bytes just gives you a different view on the underlying data, without any copying or actual converting (apart from a compile-time-kind-of type conversion)?

pub fn func(s: &str) -> &[u8] { s.as_bytes() }

pub fn noop(x: u128) -> u128 { x }

Both these functions apparently generate the same assembly code:

        mov     rdx, rsi
        mov     rax, rdi
        ret

The reference is copied/transmuted. Its referent, the text/bytes of the string, is not.

4 Likes

This is something where Rust's lifetimes can help.

The signature is <'a> &'a str -> &'a [u8]. That tells you three things:

  • The input is immutably borrowed (well, you have to know that str doesn't have interior mutability, but that's the normal case, and is essential for string literals, so hopefully it's not a surprise), so whatever it's doing can't change the input string
  • The output is a reference, so it has to be returning a reference to something that already exists (as opposed to if it were -> String or -> Vec<u8>, which is owned and thus could be something new)
  • The output reference has the same lifetime as the input lifetime, so it must be returning a reference to the same stuff that was passed in (well, technically it could also return a static, but you know that as_bytes isn't doing return &[1, 2, 3];)

Thus yes, it's a different view on the same underlying data.

(You can apply this same kind of thinking to understand other things like from_ref in std::array - Rust too.)

4 Likes

Thanks - that's a helpful addition. I'm still getting used to lifetimes and borrowing :slight_smile:

1 Like

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.