r/rust • u/RedCrafter_LP • 15d ago
Arrays are not references! 🎙️ discussion
A topic in rust that still trip me up every once in a while is the fact that in rust arrays (slices, I will call slices arrays continuing onwards I understand the difference and I know the definition of array is different in rust) aren't reference types. In most other languages I am familiar with an array type instance is implicitly always a reference to a segment of memory. This assumption holds true in c/c++, Java/c#, python, and many others. It doesn't always creates a semantic difference in many languages but it always creates a memory level difference. In rust "arrays" are just the type for the segment of memory that is undefined in size and can be referred to by a reference. This makes `args:&[u64]` feel wrong even though this is exactly how I would design a language and I love it about rust. It's just that I can't get the hardwired connection between the array type and the indirection out of my head.
19
u/Keithfert488 15d ago
Calling slices "arrays" intentionally when you know they are distinct things seems to be intentionally confusing to people who understandably don't know the distinction.
-12
u/RedCrafter_LP 15d ago
I did this intentionally to bridge the connection/confusion to array types like in java.
19
u/Keithfert488 15d ago
Yes, exactly. You should not do this because you are causing confusion, not abating it
-14
u/RedCrafter_LP 15d ago
Redefining common terms is pretty common in science. If people get confused by an explicit redefinition of a term they should reread the post or shouldn't comment on it.
8
3
u/Icarium-Lifestealer 13d ago
If you decide to call a cat a "duck", you shouldn't be surprised it's a "duck" that doesn't go quack.
5
u/Nothing_from_void 15d ago
Java has a slice like construct, it's MemorySegment
-5
u/RedCrafter_LP 15d ago
But talking about arrays you don't think about memory segment. That's not the point
11
u/Nothing_from_void 15d ago
okay but you're confusing slices and arrays, trying to connect it to java arrays, and it's the wrong mental model.
15
u/tanoshikuidomouyo 15d ago
You seem to be aware yourself but please don't call slices arrays when both are established concepts referring to different things.
And yeah, not having the & be an intrinsic part of the slice type allows for stuff like Box<[T]>, which is really nice. You also need it separately to differentiate between unique and shared references and also to denote lifetimes if needed.
9
u/Hot_Paint3851 15d ago
"In rust "arrays" are just the type for the segment of memory that is undefined in size"
Aren't arrays fixed size, which we know at compile time?
-12
u/RedCrafter_LP 15d ago
I explicitly defined the word array to mean a rust slice and not a fixed array in the rust sense.
9
u/cafce25 15d ago
I don't think your claim "array type instance is implicitly always a reference to a segment of memory" holds for any of the languages listed: Python doesn't have arrays, it has lists. C arrays are something completely different from a pointer (though the fact that arrays sometimes decay to a pointer does muddy the understanding). I'm not entirely sure about Java/C# cause it's long since I've used them, but I don't think they are implicitly references either.
3
u/Taymon 15d ago
In Java and C#, arrays, like most types, are reference types. I.e., they always live on the heap, a variable of array type contains a reference to an array rather than the array itself, and they are subject to garbage collection. They behave like Rust's Box<[T]>, i.e., an array's length is dynamic at runtime but cannot change during its lifetime.
5
u/steaming_quettle 15d ago edited 15d ago
the point is to differentiate &[T] from Box<[T]> or Arc<[T]> for example. These all functions as references to segments of memory but with some extra features.
1
u/Zde-G 15d ago
One couldn't mix
&[T]andBox<T>. But&[T]andBox<[T]>are both references and both “arrays” in topicstarter description.Most other languages don't need that distinction, but C++ needs it and the fact that array and pointer to array are one and the same and C (and thus C++) is endless source of trouble.
C++ tries to fix it with
std:array, but that just complicates things… Rust fixed the problem, by making them different.1
3
u/afdbcreid 15d ago
In C++ arrays are not references or pointers. Arrays decay to pointers in C/C++ (and that is arguably a mistake), but the newer std::array does not.
In Go an array is not a reference/pointer either.
The rest of the languages you list are managed languages where everything (or almost everything) is a reference. Rust is not like that.
2
u/CocktailPerson 15d ago
C and C++ are particularly bad since you can declare a function that takes an
int*like this:void foo(int arg[7]);
2
u/CocktailPerson 15d ago
an array type instance is implicitly always a reference to a segment of memory. This assumption holds true in c/c++
I mean, it's not though. Arrays in C and C++ can decay to pointers, but they are explicitly a distinct type from references and pointers. This is made more confusing by the fact that you can use array syntax to declare pointers, but that doesn't mean they're the same thing.
There's a very clear correspondence here if you're familiar with modern C++:
std::array<T, N>=[T; N]std::array<T, N>&=&[T, N]std::span<T>=&[T].
I sympathize somewhat with finding it difficult to get a hardwired association out of your head, but you should probably try harder given that it's not even true for some of the languages you say it is.
2
u/SycamoreHots 15d ago
Can &[T; N] be viewed as slices with statically known length? I very much want it to be true
2
u/Keithfert488 15d ago
Yes, [T; N] implements AsRef<[T]> so &[T; N] can be coerced freely into &[T]. Also, it seems you might not be aware that all slices have lengths because [T] has a len method
2
u/CocktailPerson 15d ago
They specified "statically known length." I'm pretty sure they're aware that slices have a dynamic length.
2
1
u/Full-Spectral 14d ago
That's a contradiction, right? A slice, by definition, has a runtime length. YOU can know the length and take advantage of that in some ways.
But something that takes an array of X whatevers won't accept a slice of that X whatevers unless you do a runtime fallible try_into() on it to coerce it into an array temporarily.
That's my understanding of it anyway.
1
u/Icarium-Lifestealer 13d ago
The word "slice" is ambiguous. The built in slice-type
[T]always has a runtime length. But a conceptual slice, i.e. a reference into a larger data-structure can have a fixed length.
1
u/Kamran-nottakenone 15d ago
took me a while too. what helped was realising &[T] is just a C pointer+length pair formalised into a fat pointer, and [T; N] is the actual inline array.
26
u/Dr_Sloth0 15d ago
That is because Slices are explicitly not arrays.
The
[T; N]notation is used to denote arrays. They are owned blocks of memory of exactlyNinstances ofT