Square brackets make array code look deceptively portable. In Rust, [10, 20, 30] can be a fixed-size array whose length is part of its type. In Python, the same visual shape creates a mutable list. PHP uses bracket syntax for an ordered map, while JavaScript creates a resizable Array object.
The syntax is easy to memorize. The more important distinction is what the value means after it has been created.
| Language | Common syntax | Size model | Typical growable sequence |
|---|---|---|---|
| Go | [3]int{10, 20, 30} |
Array length is fixed and part of the type | []int slice |
| PHP | [10, 20, 30] |
Dynamic | PHP array |
| JavaScript | [10, 20, 30] |
Dynamic | Array |
| Kotlin | arrayOf(10, 20, 30) |
Fixed-size array | MutableList |
| Rust | [10, 20, 30] |
Array length is fixed and part of the type | Vec<T> |
| Python | [10, 20, 30] |
Dynamic | list |
Go separates arrays from slices
Go has both arrays and slices, and the distinction is visible directly in the type.
A fixed-size array includes its length:
values := [3]int{10, 20, 30}The type of values is [3]int. A [3]int and a [4]int are different types, even though both contain int elements.
A slice omits the length:
values := []int{10, 20, 30}
values = append(values, 40)The type is []int. A slice is a descriptor over an underlying array, with a length and capacity. append may reuse the existing underlying array or allocate another one when capacity is insufficient.
That makes the common Go equivalent of a growable array a slice rather than an array.
Indexing uses the familiar bracket form:
first := values[0]
values[1] = 99Go arrays and slices are homogeneous: every element has the same element type.
PHP arrays are ordered maps
PHP uses square brackets for its array type:
$values = [10, 20, 30];
$values[] = 40;This looks like a conventional dynamic array, but PHP defines an array as an ordered map. Keys can be integers or strings.
Sequential values receive integer keys automatically:
$values = [
0 => 10,
1 => 20,
2 => 30,
];The same type can also be used as a key-value map:
$user = [
'name' => 'Mira',
'age' => 28,
];That flexibility is specific to PHP’s data model. A PHP array can act as a list, dictionary, stack, queue, or other collection shape without changing to a different built-in container type.
Elements are accessed with brackets in both cases:
echo $values[0];
echo $user['name'];PHP arrays can also hold values of different types in the same array.
JavaScript arrays are resizable objects
JavaScript’s array literal uses square brackets:
const values = [10, 20, 30];
values.push(40);Array is a resizable object with integer-indexed elements and a length property. The elements do not have to share one runtime type:
const mixed = [10, "twenty", true];JavaScript arrays are not associative arrays. Arbitrary string properties can exist on the object, but they are not array indexes and do not behave like indexed elements.
Mutation uses normal indexing:
const values = [10, 20, 30];
values[1] = 99;
console.log(values[0]);
console.log(values.length);Arrays can also be sparse. Assigning to a distant index can increase length while leaving indexes in between empty.
That makes JavaScript’s Array more dynamic than the fixed-size array types in Go, Kotlin, and Rust.
Kotlin arrays have fixed size
Kotlin creates a generic object array with arrayOf():
val values = arrayOf(10, 20, 30)
values[1] = 99
println(values[0])The array contents are mutable, but the number of slots is fixed after creation. Adding a fourth element requires creating another array.
Kotlin also provides specialized primitive arrays:
val integers = intArrayOf(10, 20, 30)
val doubles = doubleArrayOf(1.5, 2.5, 3.5)These types avoid using boxed primitive objects in the array representation.
For a collection that grows and shrinks, Kotlin normally uses a mutable collection instead:
val values = mutableListOf(10, 20, 30)
values.add(40)
values.removeAt(0)So Array<T> is closer to a fixed-size container, while MutableList<T> is the more direct equivalent of a typical growable application-level sequence.
Rust makes the length part of the array type
Rust array types have the form [T; N], where T is the element type and N is the length:
let values: [i32; 3] = [10, 20, 30];The compiler can usually infer the type:
let values = [10, 20, 30];A repeated value can use the repetition form:
let zeros = [0; 8];That creates an array containing eight zeroes.
Rust arrays have fixed length. The growable contiguous collection is Vec<T>:
let mut values = vec![10, 20, 30];
values.push(40);
values[1] = 99;Like Rust arrays, a Vec<T> is homogeneous. Every element must have the same type T.
The distinction between [T; N] and Vec<T> is semantically important. The former carries its length in the type; the latter carries a runtime length and capacity and can reallocate as it grows.
Python’s bracket literal creates a list
Python’s common bracket syntax creates a list:
values = [10, 20, 30]
values.append(40)
values[1] = 99A list is a mutable sequence and can grow or shrink after creation:
values = [10, 20, 30]
values.append(40)
values.insert(1, 15)
values.pop()Python does not require all list elements to have the same runtime type:
mixed = [10, "twenty", True]That is legal even though many programs deliberately keep list contents conceptually homogeneous.
Python also has other sequence representations, such as tuples, array.array, bytes, bytearray, and third-party numerical arrays. But when ordinary Python code writes [a, b, c], the result is a list, not a fixed-size array type.
Similar syntax does not imply equivalent behavior
The following expressions look closely related:
Go [3]int{10, 20, 30}
PHP [10, 20, 30]
JavaScript [10, 20, 30]
Kotlin arrayOf(10, 20, 30)
Rust [10, 20, 30]
Python [10, 20, 30]Their contracts are different.
Go and Rust have true fixed-size array types with the length encoded in the type. Kotlin arrays are also fixed-size, although the length is not written as part of the generic type name. JavaScript arrays and Python lists are mutable, growable sequences. PHP’s array goes further and combines ordered sequence behavior with map-style keys.
Those differences affect function signatures, copying, equality, memory layout, append behavior, and interoperability. A direct syntax translation can therefore preserve the values while changing the data structure’s semantics.
When porting code between these languages, the useful question is not merely “what is the array syntax?” It is whether the source value is supposed to be fixed-size, growable, homogeneous, key-addressable, contiguous, or merely ordered. The correct target type follows from that contract.