我正在尝试在php中创建一个循环链表,这相当简单,因为php对象是引用。这意味着 php 对象的行为应该类似于 c++ 指针。以下是链表的简化实现:
class Node{
public $next;
}
$node1 = new Node();
$node2 = new Node();
$node1->next = $node2;
$node2->next = $node1;
实现这一点后,我意识到当您在循环列表中链接对象时,疯狂的事情开始发生。 例如,使用 == 运算符比较这些对象时出现错误:
if($node1 == $node2) //Fatal error: Nesting level too deep - recursive dependency?
我发现比较这些对象的正确方法是使用严格的比较。
if($node1 === $node2) //Works fine
我认为非严格比较试图比较对象的所有属性。在这样做时,它会发现存在无限嵌套,因此它会报告错误。但是我无法弄清楚的是为什么以下方法有效:
if($node1->next == $node2) //Works fine with == rather than ===
结论:
始终使用标识运算符 (===) 来比较对象 - 除非您希望比较对具有不同实例的类似对象返回 true,但请注意嵌套问题。
据我所知,PHP 仅通过无限期地查看两个对象的属性来比较它们,直到结束。
if($node 1 == $node 2)
$node1 == $node2?
if $node1 -> next == $node2->next
if $node1->next(node2)->next == $node2->next(node1)->next
if $node1->next(node2)->next(node1)->next == $node2->next(node1)->next(node2)->next;
无限期。。。
如果一个对象具有属性,则在比较两个对象时,它将查看它们。
因此,为什么您的严格比较有效,因为它只会检查两个对象是否位于内存中的同一位置,因此它甚至不查看属性的值。
if($node 1->下一个 == $node 2)
对于为什么比较if($node 1->next == $node 2)工作正常,我想如下:如果两个要比较的对象具有相同的地址,PHP 首先比较"地址"。PHP 假定它们必须相同,因为它们驻留在同一个地方。
就像 $node 1 的地址为 1。$node 2 的地址为 2。$node 2->下一个地址为 1。相同的地址,PHP 现在不想查看属性,因为它们驻留在同一个地方。
另外,供您参考。"=="和"==="分别在 php.net 上的比较结果http://php.net/manual/en/language.oop5.object-comparison.php
Two instances of the same class
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : FALSE
o1 !== o2 : TRUE
Two references to the same instance
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : TRUE
o1 !== o2 : FALSE
Instances of two different classes
o1 == o2 : FALSE
o1 != o2 : TRUE
o1 === o2 : FALSE
o1 !== o2 : TRUE
正如您在使用 "==" 进行 php 对象比较中得出的结论,涉及比较对象的属性,并且可以变得递归
使用比较运算符 (==) 时,对象变量为 以简单的方式进行比较,即:两个对象实例相等,如果 它们具有相同的属性和值,并且是 同一类。
另一方面,当使用恒等运算符 (===) 时,对象 变量相同当且仅当它们引用同一实例时 属于同一类。
现在在后一种情况下它有效,因为您正在比较节点 2 和节点 2。 例如:
if($node2 == $node2) //works since there it can conclude in 1 step both are same objects
而
if($node2->next == $node2) //will still have the recursion issue since it has to follow the links