阅读(3578) (0)

Lambdas介绍

2017-11-21 10:32:28 更新

Hack支持通过名为lambda的构造来创建闭包。Lambdas通常不像PHP关闭那么冗长,经常和类似的函数一起使用array_filter() 要么 array_map()

语法

一个lambda由lambda运算符 引入==>。左边==>是关闭的参数列表。右边是一个用大括号括起来的表达式或者语句列表{}。请参阅lambda设计了解更多信息。

区别于传统的关闭

这个例子展示了如何使用更短的lambda语法。它还使用了一个Vector,这是Hack的集合类之一。

<?hh

namespace Hack\UserDocumentation\Lambdas\Examples\Examples\Introduction;

function addLastname(): Vector<string> {
  $people = Vector {
      "Carlton",
      "Will",
      "Phil"
  };
  return $people->map($name ==> $name . " Banks");
}

function run(): void {
  var_dump(addLastname());
}

run();

Output

object(HH\Vector)#3 (3) {
  [0]=>
  string(13) "Carlton Banks"
  [1]=>
  string(10) "Will Banks"
  [2]=>
  string(10) "Phil Banks"
}

上面的例子等价于下面的例子,使用PHP的匿名函数的传统语法。您应该看到,lambda使代码更易读,更短。

<?hh

namespace Hack\UserDocumentation\Lambdas\Examples\Examples\Difference;

function addLastnameTraditional(): array<string> {
  $people = array(
    "Carlton",
    "Will",
    "Phil"
  );
  return array_map(function ($name) {
    return $name . " Banks";
  }, $people);
}

function run(): void {
  var_dump(addLastnameTraditional());
}

run();

Output

array(3) {
  [0]=>
  string(13) "Carlton Banks"
  [1]=>
  string(10) "Will Banks"
  [2]=>
  string(10) "Phil Banks"
}

从本质上讲,传统封闭function ($name)和return从传统封闭取而代之的是更短$name ==>。

捕获变量

PHP提供关键字use来捕获封闭范围中的变量。Hack的lambda使这更容易。你可以在lambda中隐式使用变量。

<?hh

namespace Hack\UserDocumentation\Lambdas\Examples\Examples\CaptureVariables;

function addLastname(string $lastname): Vector<string> {
  $people = Vector {
      "Carlton",
      "Will",
      "Phil"
  };
  return $people->map($name ==> $name . " " . $lastname);
}

function addLastnameTraditional(string $lastname): array<string> {
  $people = array(
      "Carlton",
      "Will",
      "Phil"
  );
  return array_map(function ($name) use ($lastname) {
    return $name . " " . $lastname;
  }, $people);
}

function run(): void {
  var_dump(addLastnameTraditional("Smith"));
  var_dump(addLastname("Smith"));
}

run();

Output

array(3) {
  [0]=>
  string(13) "Carlton Smith"
  [1]=>
  string(10) "Will Smith"
  [2]=>
  string(10) "Phil Smith"
}
object(HH\Vector)#8 (3) {
  [0]=>
  string(13) "Carlton Smith"
  [1]=>
  string(10) "Will Smith"
  [2]=>
  string(10) "Phil Smith"
}

请注意,addLastName()我们$lastname直接在lambda 中使用传入的参数,而在in中addLastNameTraditional,参数$lastName必须明确捕获并在a中调用use。

注意:所有捕获的变量都是按值捕获的; 不支持通过引用进行捕获。如果您需要通过引用捕获,请使用完整的PHP关闭。