【问题标题】:Lazy evaluation of any Closure in PHPPHP中任何闭包的延迟评估
【发布时间】:2014-12-24 15:49:04
【问题描述】:

我正在寻找与上下文无关的延迟闭包评估。在伪代码中:

// imagine there's a special type of "deferred" variables
$var = (deferred) function () {
    // do something very expensive to calculate
    return 42;
};

// do something else - we do not need to know $var value here,
// or may not need to know it at all

var_dump($var * 2);
// after some million years it prints: int(84)

// now this is the hardest part...
var_dump($var); // notice no brackets here
// prints immediately as we already know it: int(42)

最后一步至关重要:这样我们可以传递一个变量(或一个类成员),而无需任何人知道它实际上是什么,直到他们使用它。

显然,我不能在语言中完全做到这一点,因为即使使用字符串 __toString() 魔术方法也不会替换原始值。甚至它也不能与字符串以外的任何东西一起使用:

// this will fail
function __toString()
{
    return new Something();
}

当然,我可以用另一个对象包裹闭包,但这意味着堆栈中的每个人都必须知道如何处理它。而这正是我想要避免的。

这甚至是遥不可及的吗?也许在某个地方有一个 hacky PECL 可以执行此操作或类似的操作。

【问题讨论】:

  • 嗨@sanmai,你有没有找到任何方法来做到这一点?我想做同样的事情,并且无法找到一种方法,而不必“调用”函数/对象/闭包来获取值。

标签: php closures lazy-evaluation


【解决方案1】:

我想你想要的是备忘录。

http://en.wikipedia.org/wiki/Memoization

这是 PHP 中那些未记录的特性之一。基本上,您在闭包中声明一个静态变量并将其用作缓存。

$var = function(){
    static $foo; // this is a memo, it sticks only to the closure
    if (isset($foo)) return $foo;
    $foo = expensive calculation
    return $foo;
};

var_dump($var()); // millions of years
var_dump($var()); // instant

这将延迟计算并缓存计算。

如果您的意思是“延迟”,就像在后台运行它们一样,您不能这样做,因为 PHP 不是多线程的。您必须设置多进程工作线程或使用 pthread。

http://php.net/manual/en/book.pthreads.php

【讨论】:

  • 不错的尝试。你不能直接访问这样的变量,没有括号。它对用户不透明(需要特殊处理),因此并不比具有解析方法的包装器对象好多少。 (此处的延迟与其他延迟无关。)
  • 除非你传递一个使用 __get() 的对象,否则你想要做的事情不能没有括号。我认为不需要括号是不现实的,不诚实的,并且没有 __get() 就无法完成。我的回答是正确的。对不起。
  • 这也不是问题的主题。闭包是函数。必须调用它们。
  • 我希望在幕后调用一个闭包,对用户不可见,并且它的结果存储在分配给它的变量中。你猜怎么着:我没有必要让别人这样做用括号,因为我也可以发明一堆方法来处理他们。
  • 你现在可以我给你看了。我认为你对自己在做什么一无所知。
猜你喜欢
  • 1970-01-01
  • 2019-06-19
  • 2021-08-13
  • 1970-01-01
  • 2011-03-03
  • 1970-01-01
  • 2021-05-17
  • 2016-06-20
  • 1970-01-01
相关资源
最近更新 更多