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.