&str is same with slice?

let s: &str = "Hello, world!";

The type of s here is &str: it’s a slice pointing to that specific point of the binary. This is also why string literals are immutable; &str is an immutable reference.

How could it be a slice when I made it myself. If it's a slice means that rust stores strings then I borrow those values for my own code?

I can understand if the slice is from String like below code. But when &str is called slice I don't know, why we have to borrow value.

fn main() {
let s = String::from("hello");

// Slice from s
let slice = &s[0..2];

}
2 Likes

A slice is a reference to a range of memory. The memory could be in the executable (literal strings), on the stack, on the heap, or elsewhere. Since the executable's data lives for the lifetime of the process, borrows from it have 'static lifetime.

3 Likes

There is conflicting nomenclature around slices. Some will call, &str a "slice", others will call it a "slice reference" or "reference to a slice" and consider str to be the type for "slices". The & in the type is to distinguish to other ways of referencing or owning string slices, like &mut str (rarely used) or Box<str> or Arc<str> for example.

The & in the slicing expression &s[0..2] is to distinguish from creation of mutable slices via &mut s[0..2] of type &mut str. For string slices, these are rarely used, because they're not super useful, but for the slice type [T], both types &[T] and &mut [T] are commonly used, and the slicing syntax there goes through the same mechanism: the Index (or IndexMut) trait. Which is concerned with more than just slicing. If you call &v[i] or &mut v[i] or v[i] on a vector or array, you'll get references or copies of the value at a given index. The & has meaning and distinguishes various cases.

9 Likes

Language around slices tends to be pretty loose, but let me present a more formal set of definitions first.

  1. A slice, [T], is a series of T in contiguous memory (layed out one after another, with proper alignment). It could have any length at run time; we say it is a dynamically sized type (DST), or an unsized type, or a type that does not implement Sized.

  2. A shared slice, &[T], is a shared reference to a slice. It's a wide reference consisting of a pointer to the memory of the slice, and the number of elements.

  3. An exclusive slice, &mut [T], is like a shared slice only the borrow is exclusive (so you can e.g. overwrite elements through it).

But most conversation and even official documentation will refer to all of [T], &[T], and &mut [T] as "a slice".[1] I'm afraid you'll just have to get used to figuring out which they meant from context.

Slices ([T]) can be on the stack, on the heap, in static memory, or whatever. They don't "care" where they are. So shared and exclusive slices may point to some variable on the stack, such as an array; or to some data on the heap, such as in a Vec; or to some data in static memory, like a static value or literal in your code. You might get one to borrowed data someone else owns, you might create one to data you own, or you might have one that technically no one owns because it's in static memory and lasts for the entire runtime of your program.

Shared and exclusives slices (&[T], &mut [T]) never own the T themselves, because they are references / a type of borrow.


A Vec<T> is an owned, growable buffer that stores Ts in contiguous memory. You can conceptually think of this as something that owns a slice of [T]. You can index into a Vec<T> with a range and get back a shared or exclusive slice.

A String is, under the hood, like a Vec<u8> which has additional guarantees -- namely, that the bytes are valid UTF8. A &str is like a &[u8] that has the same guarantee. You can index into a String with a range and get back a &str (or &mut str).

A literal &str, like "something in double quotes", is a &'static str pointing at static memory containing the contents of the literal.

As with slices, when you have a &str, you might be borrowing something you also own (e.g. in a String), you might be borrowing something someone else owns, or you might be borrowing something from static memory, etc.

You can treat a &str like a &[u8]. But you can't safely treat a &[u8] like a &str without checking it first, because the bytes might not be valid UTF8.


Other data structures that can be considered a form of owned slices other than Vec<T> include:

  • [T; N] is an array with a compile-time known length; it's like a slice ([T]) but the length is known at compile time (so it is Sized). The length is also part of the type. It's not growable.

  • Box<[T]>, a "boxed slice"; this is similar to a Vec<T> in that it owns the T and stores them on the heap. The length is stored at runtime, and isn't known at compile time. But unlike a Vec<T>, the buffer is not growable (or shrinkable).

  • Arc<[T]> and Rc<[T]> are shared owneship variations on Box<[T]>.

  • There are other combinations too (Box<[T; N]>, etc.)

  • And similar variations for UTF8 data (Box<str>, Arc<str>, Rc<str>)

You can create shared slices to these other types of owned slices too.

Technically, just a single T is like a [T; 1] (it has the same layout in memory). So if you squint just right, every owned T is also a form of owned slice with length 1. And indeed, you can create &[T] and &mut [T] (and array versions too) from &T and &mut T.


  1. There's even a pretty bad example of this right in the official documentation, which says a slice is a [T] and then immediately says it's a pointer and a length; &[T] and &mut [T] are a pointer and a length, but [T] is not a pointer, not a length, and not a pointer and a length. A [T] is the data itself, which &[T] points to. ↩︎

24 Likes

Well. Let's think about the word "slice" in the way normal people use it.

Think of slicing a rectangular cake. You can make 7 cuts across it and end up with 8 slices of cake. Make 3 cuts and you have 4 slices. Make 1 cut and you have two slices

But you could make that one cut close to one end of the cake and end up with one "slice" off the cake and the rest of the cake remains. But really that can be seen as one thin slice and one fat slice (the rest of the cake).

But now, move that one cut up to the very end of the cake, what do you have? One zero size thin slice and one big thick slice the rest of the cake.

Well that is like what happens when you do:

 let s: &str = "Hello, world!";

Here the whole cake is the bytes of "Hello world" sitting in your memory and the slice you have made takes the whole cake!

Alternatively we could see the bytes of that "Hello world" as a slice that sits in the middle of the entire cake, the cake being all of your memory space.

Either way, "slice" seems like quite a reasonable name for what is going on in Rust.

3 Likes

Please explain your question in correct English or ask someone for help if you can't do it by yourself. I'm seriously having trouble deciphering what you are asking.

There is nothing wrong with creating a string slice yourself or with using a string literal. A "string slice" is another name for str, and a reference to a string slice is an &str (with some lifetime). String literals have type &'static str. What is it that seems out of place about that?

1 Like

That's a rather difficult request. For many geographic locations, finding an acquaintance that is both a fluent English speaker, and a Rust enthusiast, and willing to help edit forum posts may be difficult.

9 Likes

However, it's certainly necessary. I'm honestly still not sure what the actual question was. I can make educated guesses, but there is so little context to work with (very short code, no errors, it doesn't actually do anything) that such guesswork is very hard and inevitably involves strong assumptions.

1 Like

May be necessary but pretty much impossible. Imagine yourself trying to form a question in Ukrainian or Chinese or whatever language you don't know.

Us native English speakers have to accommodate the fact that most of the world that speaks English is not doing so as a native langue. It is often their second or even third language. And as such can be far from perfect, especially when used in technical fields. Heck most native English speakers don't even know a second language let alone a third.

Here I guesses that qoori was likely confused by the word "slice". If they learned that &str takes a slice of String then it is understandable that seeing it used other than on a String is a bit odd. Seeing it used in such a way that it take the whole literal string and not just a part of it is a bit odd.

At least that was by guess.

Hence my diversion into the common, not computing, use of the word slice.

7 Likes

Because the bytes that make up "hello" exist in a read only section of memory, as does the code you are running and other things. As such one cannot take ownership of it because that would allow for one to write to it, which is not allowed. Hence one has to borrow it with &.

2 Likes

I would do exactly what I recommended to OP: ask for help from a fluent speaker. I have in fact done so, even in the context of languages I do speak when it mattered (namely, for translating the abstract of my thesis to French and Italian).

I was emphatically not asking OP to suddenly learn English perfectly. I was asking him/her to take steps necessary for ending up with a useful, actionable, understandable, answerable question.

I am not a native speaker of English.

2 Likes

Obviously a good first step. Of course it is not always possible to find one, likely quite difficult.

Even if one is lucky enough to have a fluent English speaker to hand I really wonder how helpful they could be presented with a snippet of Rust code or even the Rust documentation.

A good idea. But if those "necessary" steps are not an option a good start is to come here and ask and ask the question as best one can. Heck even ask the question in ones native language as well. After all that is what this forum is supposed to be about. We can be smart enough to work it out, even if it might take a bit of to and fro to arrive at the right question and answer.

Sorry. A rash assumption on my part.

1 Like

On that note, it's becoming easier. The likes of ChatGPT offer higher quality translations than available before (though I cannot judge how well languages with less digital presence are supported), and enable you to get machine-generated feedback and ideas for improvements on texts in broken English, similar to asking a native for help, quickly and for free, without needing to know and bother actual people. I wouldn't necessarily rely on it to outright answer my technical questions reliably, but as a language model it does do very good with creating proper/correct English, or adjusting texts without changing the meaning.

2 Likes

Interestingly I took a question that was asked here about a year ago put it to ChatGPT. It was a question about rewriting someone's snippet in more idiomatic Rust. I was curious about that question as it had triggered quite a long discussion with a lot of different suggestions, most of them seemed longer, more complex and incomprehensible than the original given snippet. The neatest, most elegant solution did not arise till then end of the thread.

Amazingly in the ensuing conversation with ChatGPT we went through solutions that covered most of the approaches in that thread and ended up in the same place!

That was impressive but makes me think that getting satisfactory answers out of ChatGPT is not so easy.

1 Like

Thanks for the reply, have a good day. Indeed, my question is not clear because it uses google translate. I was thinking about String and string literals for one night. Finally, when asking, I don't know how to phrase this question. Previously I have used chat GPT.

"what does it mean that string literals have been defined in the source code and memory for string literals has been prepared?"

Next time I'll make the question clear. So sorry about that.

Regards, qoori.

1 Like

Ah, so I see it speaks your native language to some degree, cool! You can easily just try to ask it to translate a text into English then, and because it understands meaning very well, it will generally do a lot better and more coherent translation job than Google Translate (at least in my experience for German and Japanese). I wouldn't necessarily outright ask it to answer the question you have, at least if it's a question where you can't easily verify the answer yourself, because it's impossible to recognize when it's giving correct answers and when it's confidently producing nonsense, or maybe partially correct, but subtly yet significantly inaccurate explanations.

2 Likes

Okay, thank you :smile:

Selamat pagi!

Saya tahu sedikit Bahasa Indonesia. But only very little. I went to UMass Amherst for grad school, they have a vibrant Indonesian community there, I made some nice friends there.

I remember three years ago or so, the Rust website was available in a number of languages, including Indonesian. I wonder if we can have that again!

Sampai jumpa lagi!
Oliver

3 Likes

Selamat pagi Oliver :smiley:

I'm also waiting for Bahasa Indonesia. Thank you, i'll add more reading sources about Rust.

Sampai jumpa, senang berinteraksi dengan mu.
Qori.

Senang bertemu denganmu juga, terima kasih!

1 Like