PHP Conference Japan 2024

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

/*
计数:4
有效:false <== 首先需要注意的是,除非先回绕,否则没有有效的指针
当前:NULL <== 因此没有当前值
键:0 <== 但我们有一个有效的键
offsetGet(键):数组 ( <== 的确如此
'id' => 1,
)
第一次移位:数组 ( <== 移位确实返回第一行
'id' => 1,
)
计数:3 <== 计数按预期维护
有效:false <== 但内部指针留在了有效范围之外
当前:NULL <== 因此再次没有当前值
键:0 <== 但我们仍然有一个有效的键
offsetGet(键):数组 ( <== 的确如此
'id' => 2,
)
第二次移位:数组 ( <== 移位确实返回第一行
'id' => 2,
)
计数:2 <== 计数按预期维护
有效:false <== 仍然无效等等..
当前:NULL
键:0
offsetGet(键):数组 (
'id' => 3,
)
回绕... <== 现在回绕
当前:数组 ( <== 耶,有一个当前值
'id' => 3,
)
第三次移位:数组 ( <== 移位正常
'id' => 3,
)
计数:1 <== 计数正常
有效:true <== 哎呀,有效
当前:NULL <== 但没有当前值
键:0 <== 我们的键仍然有效 :o
offsetGet(键):数组 (
'id' => 4,
)
*/
?>

结论:我可能遗漏了 SplDoublyLinkedList::shift 为什么首先没有维护正确的内部索引的原因,但我发现即使能够最终得到一个有效的 valid() 和一个有效的 key(),却没有 current(),而显然存在一个 current(),这更令人困惑。

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