4

To give an example, let's assume I have a type foo of the following shape,

type foo = shape(
  ?'bar' => float,
  ...
);

Now if I try to access value of field bar in the following way,

do_something_with($rcvd['bar']);

where $rcvd is of foo type, it doesn't work as bar is an optional member and might not exist for the instance $rcvd. So for this given example, the question would be - how to access the member bar of $rcvd?

Fallen
  • 4,435
  • 2
  • 26
  • 46

2 Answers2

7

Ok, found it: https://docs.hhvm.com/hack/reference/class/HH.Shapes/idx/

So the correct way is,

Shapes::idx($rcvd, 'bar');
Fallen
  • 4,435
  • 2
  • 26
  • 46
  • 1
    At some point (this may have already happened?) the notion of "nullable fields" and "optional fields" will get separated. What you have there is IIRC an optional but non-nullable field; you may want to try `'bar' => ?float` for a required but optional field. – Josh Watzman Mar 26 '18 at 20:15
1

You can use the Shapes::idx method as you mentioned in your answer.

but you can also use null coalesce operator, which you might be more familiar with from other programming languages such as PHP and C#.

see : https://docs.hhvm.com/hack/expressions-and-operators/coalesce

example :

type Foo = shape(
  'bar' => ?int,
  ?'baz' => int,
);

function qux(Foo $foo): int {
  $default = 1;
  // foo[bar] is null ? set default.
  $bar = $foo['bar'] ?? $default;
  // foo[baz] doesn't exist ? set default.
  $baz = $foo['baz'] ?? $default;
  return $baz + $bar;
}

<<__EntryPoint>>
async function main(): Awaitable<noreturn> {
  echo qux(shape(
    'bar' => null,
  )); // 2
  echo qux(shape(
    'bar' => 0,
  )); // 1
  echo qux(shape(
    'bar' => 1,
  )); // 2
  echo qux(shape(
    'bar' => 4,
    'baz' => 2,
  )); // 6
  echo qux(shape(
    'bar' => null,
    'baz' => 0
  )); // 1
}

Hack also support null coalesce equal operator.

example :

// foo[bar] is null ? set foo[bar] to default
$foo['bar'] ??= $default;

// foo[baz] is missing ? set foo[baz] to default
$foo['baz'] ??= $default;
azjezz
  • 3,827
  • 1
  • 14
  • 35