4

我正在尝试在 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,但请注意嵌套问题。

4

2 回答 2

2

据我所知,PHP 仅通过无限期地查看它们的属性直到结束来比较两个对象。

如果($node1 == $node2)

 $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;

无限期...

如果一个对象具有属性,如果您比较两个对象,它将查看它们。

因此,为什么您的严格比较有效,因为它只会检查两个对象是否位于内存中的同一位置,因此它甚至不查看属性的值。

如果($node1->下一个 == $node2)

为什么比较if($node1->next == $node2)工作正常,我猜如下: PHP 首先比较“地址”,如果要比较的两个对象具有相同的地址。PHP 假定它们必须相同,因为它们位于同一个地方

就像 $node1 的地址为 1。$node2 的地址为 2。$node2->next 的地址为 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
于 2013-09-12T20:07:34.693 回答
1

正如您在 php 对象比较中得出的结论,使用“==”涉及比较对象的属性并且可以递归

使用比较运算符(==)时,对象变量的比较方式很简单,即:如果两个对象实例具有相同的属性和值,并且是同一类的实例,则它们相等。

另一方面,当使用恒等运算符 (===) 时,对象变量是相同的当且仅当它们引用同一类的同一实例时。

现在在后一种情况下它可以工作,因为您正在将 node2 与 node2 进行比较。例如:

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
于 2013-09-12T20:03:25.630 回答