【问题标题】:Change the value of a lexically scoped variable in a HHVM/Hack lambda expression?在 HHVM/Hack lambda 表达式中更改词法范围变量的值?
【发布时间】:2015-02-04 16:34:30
【问题描述】:

是否可以在 Hack lambda 表达式中更改词法范围变量的值?

function allTrue(Map<string, bool> $map): bool {
    $valid = 1;
    $map->map($a ==> $valid &= $a);
    return $valid === 1;
}

$map = Map{'foo' => true, 'bar' => false };
var_dump(allTrue($map)); // true

我希望返回值为false

【问题讨论】:

    标签: lambda closures hhvm lexical-scope hacklang


    【解决方案1】:

    不幸的是,Hack lambda 表达式不支持这一点。但是,您仍然可以使用 PHP 5.3 闭包语法。

    function allTrue(Map<string, bool> $map): bool {
        $valid = 1;
        $map->map(function ($a) use (&$valid) {
            $valid &= $a;
        });
        return $valid === 1;
    }
    
    $map = Map{'foo' => true, 'bar' => false };
    var_dump(allTrue($map)); // false 
    

    之所以有效,是因为:由 lambda 表达式语法创建的闭包类型对象与 PHP 5.3 的闭包语法是可互换的;

    From the docs

    注意:
    目前对 lambda 表达式有一些限制 正在研究或考虑:

    Lambda 表达式不支持 通过引用捕获变量。如果程序员想要捕获 引用的变量,它们必须使用 PHP 5.3 闭包语法并将 “&”在“use(..)”列表中的变量前面。

    Lambda 表达式 目前不支持引用返回,但可以支持 以后添加。

    【讨论】:

      【解决方案2】:

      自 2019 年起,用户也可以使用 Ref 来解决此问题。

      function allTrue(Map<string, bool> $map): bool {
        $valid = Ref(1);
        $map->map($a ==> $valid->set($a));
        return $valid->get() === 1;
      }
      
      $map = Map{'foo' => true, 'bar' => false };
      var_dump(allTrue($map));
      

      见:https://hhvm.com/blog/2019/10/01/deprecating-references.html

      【讨论】:

        猜你喜欢
        • 2013-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-23
        • 2017-04-21
        • 2019-01-10
        • 2010-10-20
        相关资源
        最近更新 更多