【问题标题】:How to return instance of Traversable to meet following assertion code?如何返回 Traversable 的实例以满足以下断言代码?
【发布时间】:2019-09-29 05:21:35
【问题描述】:

这里我有一个具有挑战性的 php 函数,它应该返回一个 instanceof Traversable(迭代器),并且还需要满足测试这个函数的其他断言。

函数没有错误,它计算斐波那契数。功能是可以修改的,就是专门这样构造来挑战别人的。但是有一个限制,只标记为 !!! (三个感叹号)可以更改。

public function getFibonacci($n) {
        $n2 = -($n1 = 1);
        while ($n --> -1) {
            $r = $n1 += $n2 and 0 or !!![$n + 1 => $n1];
            $n2 = $n1 - $n2;
        }
        return $r;
    }

这是一个测试getFibonacci函数的phpunit代码

assertTrue(
    ($res = (getFibonacci(8))
    && ($res instanceof \Traversable)
    && count($arr = iterator_to_array($res)) === 9
    && array_keys($arr) == range(8, 0, -1)
    && array_values($arr) == [0, 1, 1, 2, 3, 5, 8, 13, 21]
);

所以希望添加一些代码而不是 !!! (三个感叹号)这样断言就会通过。

【问题讨论】:

  • 乍一看,这个函数似乎不应该工作,但它确实是完全合法的,并且没有错误)))。例如:while ($n --> -1) 一开始让我很困惑...

标签: php iterator phpunit traversable


【解决方案1】:

这是generator function

通过 yield from 的生成器委托

在 PHP 7 中,生成器委托允许您使用 yield from 关键字从另一个生成器、可遍历对象或数组中生成值。然后外部生成器将产生内部生成器、对象或数组中的所有值,直到不再有效,之后将在外部生成器中继续执行。

如果生成器与 yield from 一起使用,yield from 表达式还将返回内部生成器返回的任何值。

$r = $n1 += $n2 and 0 or !!![$n + 1 => $n1];

PS:在 PHP 中,逻辑运算符的优先级最低。因此,这个字符串等价于

$r = $n1 += $n2;
!!![$n + 1 => $n1];

【讨论】:

  • 谢谢Максим!解决了。我误导性地专注于“return $r”...
  • 你能用 Skype (mediaceh) 给我写信吗?我对此测试也有疑问。
猜你喜欢
  • 2017-09-22
  • 1970-01-01
  • 1970-01-01
  • 2019-04-29
  • 1970-01-01
  • 1970-01-01
  • 2021-07-24
  • 2016-05-27
  • 1970-01-01
相关资源
最近更新 更多