Arrays And Collections: Mutating Values
Hack arrays are value types. This makes your code easier to reason about, faster (no work required on a fresh web request), and well suited for caches.
If you really need mutation, Hack provides you with several options.
Updating value types
Updating an element in a value type creates a new copy.
function update_value(vec<int> $items): vec<int> {
// Both of these operations set $items a modified copy of the
// original value.
$items[0] = 42;
$items[] = 100;
return $items;
}
function demo(): void {
$v = vec[1, 2];
// $v is unaffected by this function call.
$v2 = update_value($v);
var_dump($v); // vec[1, 2]
var_dump($v2); // vec[42, 2, 100]
}
Value types are shallow. A mutable type inside a value type is mutated by reference.
class Person {
public function __construct(public string $name) {}
}
function update_person(vec<Person> $items): void {
$items[0]->name = "new";
}
function demo(): void {
$v = vec[new Person("old")];
update_person($v);
var_dump($v); // vec[Person { name: "new" }]
}
Using inout
to simulate mutability
You can often use inout
parameters instead of mutation. This copies
the modified parameters back to the locals of the caller.
function update_value(inout vec<int> $items): void {
$items[0] = 42;
$items[] = 100;
}
function demo(): void {
$v = vec[1, 2];
update_value(inout $v);
var_dump($v); // vec[42, 2, 100]
}
Using Ref
for shallow mutability
The Ref
class provides a single value that can be mutated.
function update_value(Ref<vec<int>> $items): void {
$inner = $items->get();
$inner[0] = 42;
$inner[] = 100;
$items->set($inner);
}
function demo(): void {
$v = new Ref(vec[1, 2]);
update_value($v);
var_dump($v->get()); // vec[42, 2, 100]
}
Using Collections for mutability
All the Collection classes are mutable. We recommend using Hack arrays
wherever possible, but you can use Vector
, Set
or Map
if you
really need to.
function update_value(Vector<int> $items): void {
$items[0] = 42;
$items[] = 100;
}
function demo(): void {
$v = Vector {1, 2};
update_value($v);
var_dump($v); // Vector {42, 2, 100}
}
Thank You!
Thank You! If you'd like to share more feedback, please file an issue.