Lambdas设计
lambda表达式使用lambda箭头表示==>。箭头的左边是匿名函数的参数,右边是大括号中的表达式或者语句列表{}。
<?hh
namespace Hack\UserDocumentation\Lambdas\Examples\Design\Introduction;
class User {
public string $name;
protected function __construct(string $name) { $this->name = $name; }
static function get(int $id): User {
// Load user from database, return a stub for the example
return new User("User" . strval($id));
}
}
function getUsersFromIds(Vector<int> $userids): Vector<User> {
return $userids->map($id ==> User::get($id));
}
function run(): void {
var_dump(getUsersFromIds(Vector { 1, 2, 3, 4 }));
}
run();
Output
object(HH\Vector)#3 (4) {
[0]=>
object(Hack\UserDocumentation\Lambdas\Examples\Design\Introduction\User)#4 (1) {
["name"]=>
string(5) "User1"
}
[1]=>
object(Hack\UserDocumentation\Lambdas\Examples\Design\Introduction\User)#5 (1) {
["name"]=>
string(5) "User2"
}
[2]=>
object(Hack\UserDocumentation\Lambdas\Examples\Design\Introduction\User)#6 (1) {
["name"]=>
string(5) "User3"
}
[3]=>
object(Hack\UserDocumentation\Lambdas\Examples\Design\Introduction\User)#7 (1) {
["name"]=>
string(5) "User4"
}
}
lambdas注释
Lambdas相当于Closures
,但你不能键入他们注释为callable
。但是,您可以:
- 注释传递或返回的lambda调用,(function(parametertypes): returntype)以提供类型信息。
- 注释lambda本身,参数和lambda返回类型。
你有更多的类型信息,你可以提前发现更多的错误。
<?hh
namespace Hack\UserDocumentation\Lambdas\Examples\Design\Annotation;
function getLambda(): (function(?int): bool) {
return $x ==> $x === null || $x === 0;
}
function annotateLambda(string $s1, string $s2): array<string> {
$strs = array($s1, $s2);
usort(
$strs,
(string $s1, string $s2): int ==> strlen($s1) - strlen($s2)
);
return $strs;
}
function run(): void {
var_dump(getLambda());
var_dump(annotateLambda('Joel', 'Tim'));
}
run();
Output
object(Closure$Hack\UserDocumentation\Lambdas\Examples\Design\Annotation\Hack\UserDocumentation\Lambdas\Examples\Design\Annotation\getLambda;1186593164)#1 (1) {
["parameter"]=>
array(1) {
["$x"]=>
string(10) "<required>"
}
}
array(2) {
[0]=>
string(3) "Tim"
[1]=>
string(4) "Joel"
}
请注意,像一个函数的定义 Vector::filter
是:
public function filter ( (function(Tv): bool) $callback ): Vector<Tv>
这样你只能传递一个返回的lambda bool。黑客推断类型,并会打印一个错误,如果你没有通过一个有效的封闭。因此,在许多情况下,您不必注释lambda表达式。
括号附近的括号
大多数情况下,你需要围绕参数括号。但是,如果只有一个没有类型注释的参数,没有默认值,并且您的lambda没有返回类型注释,则可以省略括号。有关更多信息,请参阅示例。
优先权
该==>运营商与其他运营商相比,具有较低的优先级。这很方便,因为它允许lambdas有一个复杂的身体,而不需要括号。此外,运营商是正确的联想,可以链接。
<?hh
namespace Hack\UserDocumentation\Lambdas\Examples\Design\Chained;
function chainedLambdas(): void {
$lambda = $x ==> $y ==> $x - $y;
$f = $lambda(4); // You are providing $x the value 4
echo $f(2); // You are providing $y the value 2; thus this prints 2
}
function run(): void {
chainedLambdas();
}
run();
Output
2