SplDoublyLinkedList::shift

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

SplDoublyLinkedList::shift从双向链表的开头移出节点

描述

public SplDoublyLinkedList::shift(): mixed

参数

此函数没有参数。

返回值

移出节点的值。

错误/异常

当数据结构为空时,抛出 RuntimeException

添加说明

用户贡献的说明 1 个说明

fabs2s at marsatak dot org
7 年前
人们可能期望 SplDoublyLinkedList::shift 正确维护内部指针,但事实并非如此,即使您先回溯,这也不会产生任何结果

<?php
while ($splDoublyLinkedList->valid()) {
yield
$splDoublyLinkedList->shift();
}
?>

这可能是设计使然,但以下问题引发了更多疑问

<?php

$test
= new \SplDoublyLinkedList;
$dataSet = [
[
'id' => 1],
[
'id' => 2],
[
'id' => 3],
[
'id' => 4],
];

foreach (
$dataSet as $row) {
$test->push($row);
}

echo
"count: " . $test->count() . PHP_EOL;
echo
"valid: " . ($test->valid() ? 'true' : 'false') . PHP_EOL;
echo
"current: " . var_export($test->current(), true) . PHP_EOL;
echo
"key: " . $test->key() . PHP_EOL;
echo
"1st shift: " . var_export($test->shift(), true) . PHP_EOL;
echo
"count: " . $test->count() . PHP_EOL;
echo
"valid: " . ($test->valid() ? 'true' : 'false') . PHP_EOL;
echo
"current: " . var_export($test->current(), true) . PHP_EOL;
echo
"key: " . $test->key() . PHP_EOL;
echo
"2nd shift: " . var_export($test->shift(), true) . PHP_EOL;
echo
"count: " . $test->count() . PHP_EOL;
echo
"valid: " . ($test->valid() ? 'true' : 'false') . PHP_EOL;
echo
"current: " . var_export($test->current(), true) . PHP_EOL;
echo
"key: " . $test->key() . PHP_EOL;
echo
"rewinding... " . PHP_EOL;
$test->rewind();
echo
"current: " . var_export($test->current(), true) . PHP_EOL;
echo
"2nd shift: " . var_export($test->shift(), true) . PHP_EOL;
echo
"count: " . $test->count() . PHP_EOL;
echo
"valid: " . ($test->valid() ? 'true' : 'false') . PHP_EOL;
echo
"current: " . var_export($test->current(), true) . PHP_EOL;
echo
"key: " . $test->key() . PHP_EOL;
?>

将导致
<?php

/*
count: 4
valid: false <== 首先要注意的是,除非您先回溯,否则您没有有效的指针
current: NULL <== 因此没有当前值
key: 0 <== 但我们有一个有效的键
offsetGet(key): array ( <== 的确
'id' => 1,
)
1st shift: array ( <== 并且 shift 返回第一行
'id' => 1,
)
count: 3 <== 并且计数按预期维护
valid: false <== 但内部指针被留在了有效范围之外
current: NULL <== 因此再次没有当前值
key: 0 <== 但我们仍然有一个有效的键
offsetGet(key): array ( <== 的确
'id' => 2,
)
2nd shift: array ( <== 并且 shift 返回第一行
'id' => 2,
)
count: 2 <== 并且计数按预期维护
valid: false <== 仍然无效等..
current: NULL
key: 0
offsetGet(key): array (
'id' => 3,
)
rewinding... <== 现在回溯
current: array ( <== 太棒了,有一个当前值
'id' => 3,
)
3rd shift: array ( <== shift 正常
'id' => 3,
)
count: 1 <== 计数正常
valid: true <== 哎呦,有效
current: NULL <== 且没有当前值
key: 0 <== 我们的键仍然有效 :o
offsetGet(key): array (
'id' => 4,
)
*/
?>

结论:我可能漏掉了 SplDoublyLinkedList::shift 为什么没有从一开始就维护正确的内部索引,但我发现更令人困惑的是,当显然存在一个当前值时,却能够得到有效的 valid() 和有效的 key(),而没有 current()。

在 php 5.6.30 & 7.1.2 上测试,结果完全相同。
To Top