In C-descendant/related languages, [] is the indexing operator. So broadly
var x = {2, 4, 6};
print(x[2]);
C/C++ is particular in allowing the [] on left side of the =, tied to the variable name as part of the declaration.
int32_t y[] = {5, 7, 9};
int32_t *z = y;
Serial.println(sizeof(y));
Serial.println(sizeof(z));
Serial.println(z[2]);
Those two are similar, but z is "just a pointer"; while y "decays to a pointer" but also knows its size, that it has 3 elements. sizeof(z) is the size of a pointer (2 or 4 bytes), while sizeof(y) is 3 times 4 bytes. The indexing operator works fine with a pointer.
By having no argument in the brackets, the compiler will count the number of elements and size accordingly. If you specify the count, the compiler will balk if there are too many elements, but is fine if you specify too few (leaving the gap with their default values, zero or garbage).
This initialization is the only time that name[] is allowed, with no arguments. After that the brackets are used to specify a single element. Note that the initialization is not "a lot of work" by itself. The literal array on the right of the = might be arbitrarily large, but initializing the array variable is just copying a pointer to the first element.
So oldArray[] = newArray[] is not allowed syntactically, in any C-like language. Other languages might allow oldArray = newArray, which simply results in the array reference being overwritten. But in C/C++, this is some kind of "invalid array assignment" error, even when the arrays are the same size. You can think of it as "too much work" in principle. The compiler does not want to commit to copying an arbitrary number of elements with a single assignment. You need to use a function like memcpy. But this is allowed:
struct {
int32_t i[3];
float f[3];
} a, b{{1, 2, 3}, {0.5, 0.25, 0.125}};
a = b;
Serial.println(sizeof(a));
Serial.println(a.f[2]);
Even if the struct is arbitrarily large (and contains arrays), it's still a "single object", and so assignment by copying is allowed.
Which is not to suggest that you do that. If you have three related values, instead of an array, you might use a struct like this
struct WithBetterNames {
int first;
int second;
int third;
} before{LOW, LOW, LOW}, after{HIGH, HIGH, HIGH};
Serial.println(before.third);
before = after;
Serial.println(before.third);
"Easy"/naive comparison of structs requires C++20 with the "spaceship operator" <=>
struct WithBetterNames {
int first;
int second;
int third;
auto operator<=>(const WithBetterNames&) const = default;
};
//...
Serial.println(before == after);
Some boards like ESP32 (probably) have it, while AVR does not.