PHP的飞船操作符<=>如何处理无与伦比的操作数?
How does PHP's spaceship operator <=> handle incomparable operands?
将在PHP7中添加宇宙飞船操作符。我不确定它在某些边缘情况下的工作方式。
$a <=> $b
将 return:
- 1 如果 $a > $b
- 0 如果 $a == $b
- -1 如果 $a < $b
如果值不具有可比性会怎样?
可以比较哪些变量类型?
简单!实现 macro-heavy C 的运算符 defers to a function called compare_function
in PHP's internals, so you just need to read compare_function
's 200-line implementation 的拉取请求,您将能够自己理解其行为。控制结构只有 4 层深,只有几十个宏和其他函数被调用;应该很简单!
...
好吧,我承认,我也不够聪明,无法取消所有这些。因此,让我们做一些实验。
如果 <
、==
和 >
可以一致地处理操作数,那么 <=>
也可以
由于 type juggling,PHP 中的大多数类型都可以与其他类型进行有意义的比较。在这种情况下,宇宙飞船操作员的行为方式将与 <
、==
和 >
.
一致
例如,让我们尝试使用字符串和整数:
php > <b><i>var_dump(3 < 'bla');</i></b>
bool(false)
php > <b><i>var_dump(3 == 'bla');</i></b>
bool(false)
php > <b><i>var_dump(3 > 'bla');</i></b>
bool(true)
php > <b><i>var_dump(3 <=> 'bla');</i></b>
int(1)</pre>
或使用 null
和资源:
php > <b><i>$fp = fopen('test', 'r');</i></b>
php > <b><i>var_dump(null > $fp);</i></b>
bool(false)
php > <b><i>var_dump(null == $fp);</i></b>
bool(false)
php > <b><i>var_dump(null < $fp);</i></b>
bool(true)
php > <b><i>var_dump(null <=> $fp);</i></b>
int(-1)
或者使用浮点数和数组:
php > <b><i>var_dump(1.0 > []);</i></b>
bool(false)
php > <b><i>var_dump(1.0 == []);</i></b>
bool(false)
php > <b><i>var_dump(1.0 < []);</i></b>
bool(true)
php > <b><i>var_dump(1.0 <=> []);</i></b>
int(-1)</pre>
在所有这些情况下,$a <=> $b
的结果正是文档所说的那样:-1
if $a < $b
,0
if $a == $b
, 1
如果 $a > $b
.
但是如果 <
、==
和 >
return 的 none 为真,宇宙飞船就会混淆并且 returns 1
虽然类型强制允许 most 不同类型的值相互比较,这样 $a < $b
、$a == $b
和 $a > $b
是真的,有一些边缘情况不成立。在那些情况下,$a <=> $b
的结果是 1,这不是很有意义或有用。
例如,让我们比较一些不同类的对象:
php > <b><i>class Foo {}</i></b>
php > <b><i>class Bar {}</i></b>
php > <b><i>$a = new Foo;</i></b>
php > <b><i>$b = new Bar;</i></b>
php > <b><i>var_dump($a < $b);</i></b>
bool(false)
php > <b><i>var_dump($a == $b);</i></b>
bool(false)
php > <b><i>var_dump($a > $b);</i></b>
bool(false)
php > <b><i>var_dump($a <=> $b);</i></b>
int(1)
php > <b><i>var_dump($b <=> $a);</i></b>
int(1)</pre>
或一些 non-equal 数组,其中两者都不严格大于另一个:
php > <b><i>$a = ['foo' => 'bar'];</i></b>
php > <b><i>$b = ['bar' => 'foo'];</i></b>
php > <b><i>var_dump($a < $b);</i></b>
bool(false)
php > <b><i>var_dump($a == $b);</i></b>
bool(false)
php > <b><i>var_dump($a > $b);</i></b>
bool(false)
php > <b><i>var_dump($a <=> $b);</i></b>
int(1)
php > <b><i>var_dump($b <=> $a);</i></b>
int(1)</pre>
<=>
也可以抛出警告
如果我们将一个对象与一个 int 进行比较,我们会收到警告,就像我们对任何其他比较运算符这样做一样:
php > <b><i>$a = new stdclass;</i></b>
php > <b><i>var_dump($a <=> 1);</i></b>
PHP Notice: Object of class stdClass could not be converted to int in php shell code on line 1
int(0)</pre>
不可比较类型的结果显然没有帮助,并且会混淆任何期望宇宙飞船操作员始终对不同类型的值排序的东西。因此,请勿在可能会进行此类无意义比较的情况下使用它。
将在PHP7中添加宇宙飞船操作符。我不确定它在某些边缘情况下的工作方式。
$a <=> $b
将 return:
- 1 如果 $a > $b
- 0 如果 $a == $b
- -1 如果 $a < $b
如果值不具有可比性会怎样?
可以比较哪些变量类型?
简单!实现 macro-heavy C 的运算符 defers to a function called compare_function
in PHP's internals, so you just need to read compare_function
's 200-line implementation 的拉取请求,您将能够自己理解其行为。控制结构只有 4 层深,只有几十个宏和其他函数被调用;应该很简单!
...
好吧,我承认,我也不够聪明,无法取消所有这些。因此,让我们做一些实验。
如果 <
、==
和 >
可以一致地处理操作数,那么 <=>
也可以
由于 type juggling,PHP 中的大多数类型都可以与其他类型进行有意义的比较。在这种情况下,宇宙飞船操作员的行为方式将与 <
、==
和 >
.
例如,让我们尝试使用字符串和整数:
php > <b><i>var_dump(3 < 'bla');</i></b> bool(false) php > <b><i>var_dump(3 == 'bla');</i></b> bool(false) php > <b><i>var_dump(3 > 'bla');</i></b> bool(true) php > <b><i>var_dump(3 <=> 'bla');</i></b> int(1)</pre>
或使用
null
和资源:php > <b><i>$fp = fopen('test', 'r');</i></b> php > <b><i>var_dump(null > $fp);</i></b> bool(false) php > <b><i>var_dump(null == $fp);</i></b> bool(false) php > <b><i>var_dump(null < $fp);</i></b> bool(true) php > <b><i>var_dump(null <=> $fp);</i></b> int(-1)
或者使用浮点数和数组:
php > <b><i>var_dump(1.0 > []);</i></b> bool(false) php > <b><i>var_dump(1.0 == []);</i></b> bool(false) php > <b><i>var_dump(1.0 < []);</i></b> bool(true) php > <b><i>var_dump(1.0 <=> []);</i></b> int(-1)</pre>
在所有这些情况下,
$a <=> $b
的结果正是文档所说的那样:-1
if$a < $b
,0
if$a == $b
,1
如果$a > $b
.但是如果
<
、==
和>
return 的 none 为真,宇宙飞船就会混淆并且 returns 1虽然类型强制允许 most 不同类型的值相互比较,这样
$a < $b
、$a == $b
和$a > $b
是真的,有一些边缘情况不成立。在那些情况下,$a <=> $b
的结果是 1,这不是很有意义或有用。例如,让我们比较一些不同类的对象:
php > <b><i>class Foo {}</i></b> php > <b><i>class Bar {}</i></b> php > <b><i>$a = new Foo;</i></b> php > <b><i>$b = new Bar;</i></b> php > <b><i>var_dump($a < $b);</i></b> bool(false) php > <b><i>var_dump($a == $b);</i></b> bool(false) php > <b><i>var_dump($a > $b);</i></b> bool(false) php > <b><i>var_dump($a <=> $b);</i></b> int(1) php > <b><i>var_dump($b <=> $a);</i></b> int(1)</pre>
或一些 non-equal 数组,其中两者都不严格大于另一个:
php > <b><i>$a = ['foo' => 'bar'];</i></b> php > <b><i>$b = ['bar' => 'foo'];</i></b> php > <b><i>var_dump($a < $b);</i></b> bool(false) php > <b><i>var_dump($a == $b);</i></b> bool(false) php > <b><i>var_dump($a > $b);</i></b> bool(false) php > <b><i>var_dump($a <=> $b);</i></b> int(1) php > <b><i>var_dump($b <=> $a);</i></b> int(1)</pre>
<=>
也可以抛出警告如果我们将一个对象与一个 int 进行比较,我们会收到警告,就像我们对任何其他比较运算符这样做一样:
php > <b><i>$a = new stdclass;</i></b> php > <b><i>var_dump($a <=> 1);</i></b> PHP Notice: Object of class stdClass could not be converted to int in php shell code on line 1 int(0)</pre>
不可比较类型的结果显然没有帮助,并且会混淆任何期望宇宙飞船操作员始终对不同类型的值排序的东西。因此,请勿在可能会进行此类无意义比较的情况下使用它。