Rau*_*din 3 php spaceship-operator php-7
在RFC中给出了这个例子:
Run Code Online (Sandbox Code Playgroud)// only values are compared $a = (object) ["a" => "b"]; $b = (object) ["b" => "b"]; echo $a <=> $b; // 0
但是当我执行它时,我得到 1 作为输出:
$a = (object) ["a" => "b"];
$b = (object) ["b" => "b"];
echo $a <=> $b; //1
Run Code Online (Sandbox Code Playgroud)
我现在不明白 <=> 如何比较对象?在 RFC 中,它表示仅通过值进行比较。
PS我在vagrant下使用PHP 7.0.4-6+deb.sury.org~trusty+1 (cli) ( NTS )
更新:
php > echo (object)["b"=>"b"] <=> (object)["b"=>"b"];
0
php > echo (object)["b"=>"b"] <=> (object)["a"=>"b"];
1
php > echo (object)["a"=>"b"] <=> (object)["b"=>"b"];
1
Run Code Online (Sandbox Code Playgroud)
当阅读RFC时,我们发现它是自相矛盾的:
\n\n\n\n\n添加一个新运算符 (expr) <=> (expr),如果两个操作数相等则返回 0,如果左侧较大则返回 1,如果右侧较大则返回 -1。它使用与我们现有的比较运算符完全相同的比较规则:<、<=、==、>= 和 >。(详情请参阅说明书)
\n
注意:请参阅==,这意味着飞船操作员进行了松散的比较。
稍后在示例中:
\n\n\n\n\nRun Code Online (Sandbox Code Playgroud)\n// only values are compared\n$a = (object) ["a" => "b"]; \n$b = (object) ["b" => "b"]; \necho $a $b; // 0\n
飞船算子只是算子<,==和的组合>。它根据评估结果给出相应的返回值:
operator(s): < = >\nreturn value: -1 0 1\nRun Code Online (Sandbox Code Playgroud)\n\n现在数组和对象是更复杂的类型。要了解<=>PHP spaceship 运算符的作用,我们需要查看并了解<,==和>对于数组和对象的作用。
那么让我们看看每种类型的比较运算符<, >, 。==首先我们会看看<,>然后我们也会看看==。
现在至于数组<并>记录在此处:
\n\n\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2 \x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94 \x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2 \x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94 \x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2 \x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94 \x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 \xe2\x94\x90\n\xe2\x94\x82 \xe2\x94\x82 的类型 \xe2\x94\x82 的类型 \xe2\x94\x82\n\xe2\x94\x82 操作数 1 \xe2\x94 \x82 操作数 2 \xe2\x94\x82 结果 \xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\ xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\ x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\ x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\ xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\ x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\ x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\ xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\ x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\ x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xa4\n\xe2\x94\x82 数组 \xe2\x94\x82 数组 \xe2\x94\x82 具有更少的数组成员较小, \xe2\x94\x82\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x82 如果在操作数 2 中未找到操作数 1 的键 \xe2\x94\x82\n\ xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x82 那么数组是不可比较的,\xe2\x94\x82\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x82 否则 - 逐个比较 \xe2\x94\x82\n\xe2\x94\x94\xe2\x94 \x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 \xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2 \x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94 \x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2 \x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94 \x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2 \x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n\n
这也可以用代码来编写和表示:
\n\n\n\n\n示例 #2 标准数组比较的转录
\n\nRun Code Online (Sandbox Code Playgroud)\n<?php\n// Arrays are compared like this with standard comparison operators\nfunction standard_array_compare($op1, $op2)\n{\n if (count($op1) < count($op2)) {\n return -1; // $op1 < $op2\n } elseif (count($op1) > count($op2)) {\n return 1; // $op1 > $op2\n }\n foreach ($op1 as $key => $val) {\n if (!array_key_exists($key, $op2)) {\n return null; // uncomparable\n } elseif ($val < $op2[$key]) {\n return -1;\n } elseif ($val > $op2[$key]) {\n return 1;\n }\n }\n return 0; // $op1 == $op2\n}\n?>\n
我们可以通过一些测试轻松地测试这一点。使用数学中的方法并且总是只改变一件事,所以我们可以确保我们在这里是正确的:
\n\n// only values are compared\n$a = (object) ["a" => "b"]; \n$b = (object) ["b" => "b"]; \necho $a $b; // 0\nRun Code Online (Sandbox Code Playgroud)\r\n对于相等/恒等运算符==,我们可以在此处===找到数组的文档:
\n\n\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2 \x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94 \x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2 \x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94 \x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2 \x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94 \x90\n\xe2\x94\x82 示例 \xe2\x94\x82 名称 \xe2\x94\x82 结果 \xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\ x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\ xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\ x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\ x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\ xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\ x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\ x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\ xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\ x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xa4\n\xe2\x94\x82 $a == $b \xe2\ x94\x82 相等 \xe2\x94\x82 如果 $a 和 $b 具有相同的键/值对,则为 TRUE。\xe2\x94\x82\n\xe2\x94\x82 $a === $b \xe2\x94\x82 Identity \xe2\x94\x82 如果 $a 和 $b 具有相同的键/值对,则为 TRUE \xe2 \x94\x82\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x82 具有相同的顺序和相同的类型。
和以前一样,我们可以简单地使用一些测试代码来测试它:
\n\noperator(s): < = >\nreturn value: -1 0 1\nRun Code Online (Sandbox Code Playgroud)\r\n因此,我们可以看到并确认数组的比较运算符按预期和记录的方式工作!
\n\n\n\n<\n 和>对象的文档记录在此处:
\n\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2 \x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94 \x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2 \x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94 \x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2 \x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94 \x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 \xe2\x94\x90\n\xe2\x94\x82 \xe2\x94\x82 的类型 \xe2\x94\x82 的类型 \xe2\x94\x82\n\xe2\x94\x82 操作数 1 \xe2\x94 \x82 操作数 2 \xe2\x94\x82 结果 \xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\ xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\ x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\ x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\ xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\ x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\ x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\ xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\ x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\ x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xa4\n\xe2\x94\x82 对象 \xe2\x94\x82 对象 \xe2\x94\x82 内置类可以定义自己的比较, \xe2\x94\x82 \n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x82 不同的类是不可比较的,\xe2\x94\x82\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x82 相同类比较属性与数组相同 \xe2\x94\x82\n\xe2\x94\x94\xe2\ x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\ x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\ xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\ x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\ x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\ xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\ x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\ x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\ xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
和以前一样,我们也可以测试一下:
\n\n/**\r\n/*\r\n/* Testing operators: < and >\r\n/*\r\n */ \r\n\r\n//Test case\r\n//Variations: amount, values and keys (order)\r\n//Test count: 10\r\n// Failed: 0\r\n// Passed: 10 \r\n{\r\n //Test case 1.1\r\n $a = (object)["a" => 1];\r\n $b = (object)["a" => 1];\r\n\r\n //Passed\r\n var_dump("Same amount of elements, keys and values: " . "\'<\' -> " . bool2str($a < $b) . " \'>\' -> " . bool2str($a > $b));\r\n \r\n //Test case 1.2\r\n $a = (object)["a" => 1];\r\n $b = (object)["a" => 1, "b" => 1];\r\n\r\n //Passed\r\n var_dump("NOT same amount of elements, but same values: " . "\'<\' -> " . bool2str($a < $b) . " \'>\' -> " . bool2str($a > $b));\r\n\r\n //Test case 1.3 \r\n $a = (object)["a" => 10];\r\n $b = (object)["a" => 1, "b" => 1];\r\n\r\n //Passed\r\n var_dump("NOT same amount of elements nor values: " . "\'<\' -> " . bool2str($a < $b) . " \'>\' -> " . bool2str($a > $b));\r\n \r\n //Test case 1.4\r\n $a = (object)["a" => 1];\r\n $b = (object)["b" => 1];\r\n\r\n //Passed\r\n var_dump("Same amount of element and values, NOT same keys: " . "\'<\' -> " . bool2str($a < $b) . " \'>\' -> " . bool2str($a > $b));\r\n\r\n //Test case 1.5\r\n $a = (object)["a" => 10];\r\n $b = (object)["a" => 1];\r\n\r\n //Passed\r\n var_dump("Same amount of elements and keys, NOT same values: " . "\'<\' -> " . bool2str($a < $b) . " \'>\' -> " . bool2str($a > $b));\r\n \r\n //Test case 1.6\r\n $a = (object)["a" => 1, "b" => 1];\r\n $b = (object)["b" => 1, "a" => 1];\r\n\r\n //Passed\r\n var_dump("Same amount of elements and keys in different order: " . "\'<\' -> " . bool2str($a < $b) . " \'>\' -> " . bool2str($a > $b));\r\n \r\n //Test case 1.7\r\n $a = (object)["a" => 1, "b" => 5];\r\n $b = (object)["b" => 5];\r\n\r\n //Passed\r\n var_dump("Same values, NOT same amount of elements nor keys: " . "\'<\' -> " . bool2str($a < $b) . " \'>\' -> " . bool2str($a > $b));\r\n \r\n //Test case 1.8\r\n $a = (object)["c" => 1];\r\n $b = (object)["a" => 10];\r\n\r\n //Passed\r\n var_dump("NOT same keys nor values: " . "\'<\' -> " . bool2str($a < $b) . " \'>\' -> " . bool2str($a > $b));\r\n \r\n //Test case 1.9\r\n $a = (object)["a" => 1, "b" => 1];\r\n $b = (object)["b" => 10, "a" => 1];\r\n\r\n //Passed\r\n var_dump("Same amount of elements and values, NOT same keys nor order: " . "\'<\' -> " . bool2str($a < $b) . " \'>\' -> " . bool2str($a > $b));\r\n \r\n //Test case 1.10\r\n class A {public $a = 1;}\r\n $a = new A;\r\n class B {public $a = 1;}\r\n $b = new B;\r\n\r\n //Passed\r\n var_dump("Same amount of elements and values and keys, but different not built-in class: " . "\'<\' -> " . bool2str($a < $b) . " \'>\' -> " . bool2str($a > $b));\r\n \r\n}\r\n\r\n\r\necho PHP_EOL . PHP_EOL . PHP_EOL; //Test case separator\r\n\r\n/**\r\n/*\r\n/* Test case end\r\n/*\r\n */\r\n\r\n//NULL, TRUE, FALSE