翻译自 链接

Coercion是对标量类型 (整型、浮点型、布尔型、字符串类型)。在这篇文章中,我们会看到显式类型转换的一种优雅的替代方式。

转换为整型

我们可以在任何表达式之后添加 |0 后缀 – 位运算中的按位或运算,将其转化为整型。位运算操作符 只对整型有效,所以PHP会讲两个操作数都转换为整型。并且,与0值进行按位或运算对操作数的数值无影响,所以,我们可以放心使用这一技巧。

这种转换与 (int)floor($x) , intval($x), (int)$x, (integer)$x等方式是相同的。在其它的一些语言中,也可以通过使用 ~~ (两个操作)前缀来实现。

例子

1
2
3
4
5
6
7
表达式     结果 

true|0 1
false|0 0
1.6|0 1
'1a'|0 1
'a1'|0 0

转换为浮点型

我们可以在任何表达式之后添加 +0.+.0后缀来将其转换为浮点型。浮点数可以没有整数部分或小数部分(但不能两部分都没有),这种情况下未指定的部分会被认为是0;所以,0..00.0是一样的。

这种转换与 flloat($x), doubleval($x), (float)$x, (double)$x, (real)$x是一样的。

例子

1
2
3
4
5
表达式    结果

true+0. 1.0
false+0. 0.0
'1'+0. 1.0

转换为数值类型

我们可以在任何表达式转换为数值类型;也就是,在一个整数或浮点数之前添加前缀,+-。尽管它们在算数运算符中一般被当做加号和减号,但当只有一个操作数时,我们称他们为一元加和减。+将它的操作数转换为整型或浮点型,依据的是该操作数与哪一类型更接近;-也会进行相同的操作,不过,它同时会将操作数取反。

例子

1
2
3
4
5
6
7
8
9
10
表达式        结果

+true 1
-true -1
-false 0
-'-1.6a' 1.6
+('1'.'6') 16
+'0x10' 16
+'010' 10
+'0b10' 0

转换为布尔型

我们可以将任何表达式转换为布尔型,只需要加一个!(逻辑运算符)前缀。逻辑运算符总是返回布尔值。我们使用!,是因为它是一元运算符,很简洁。使用!!可以保证原表达式的布尔值不变。

布尔转换与boolval($x), (bool)$x, (boolean)$x是一样的。

例子

1
2
3
4
5
6
7
表达式   结果

!!true true
!0 true
!!1 true
!!'a' true
!!'0' false

更多的转换结果请查看真值表

转换为字符串类型

我们可以将任何标量或对象用双引号引起来,来将其转换为字符串类型。

这种转换与 strval($x)(string)$x是一样的。

例子

Exception中实现了__toString方法提供异常的字符串表示。

1
2
$e = new Exception('foo');
"$e";

结果

1
$ exception 'Exception' with message 'foo' in -:2 
  Stack trace: 
  #0 {main}

实际应用

一些人尝试为语言提供强类型,但使用语言的上述特性,我们可以很方便的将变量转换为我们想要的类型。

例子

当我们创建getter和setter时,这种转换很有用。在下面的例子中,我们可以保证使用setInteger方法存储的变量都是整数类型。

1
2
3
4
5
6
7
class Bar {  
private $integer;

public function setInteger($integer) {
$this->integer = $integer|0;
}
}

ToString的例子

我们可以在类中实现__toString方法,这样可以避免PHP抛出致命错误。此时,我们就可以使用上面提到的方法来解决这个问题。

1
2
3
4
5
6
7
8
9
10
11
class Foo {  
public $value;

public function __toString() {
return "$this->value";
}
}

$foo = new Foo;
$foo->value = 123;
"$foo"

结果:

1
$ '123'

总结

1
2
3
4
5
6
7
类型      方式

整型 $x|0
浮点型 $x+0. 或 $x+.0
数值类型 +$x 或 -$x
布尔值 !!$x 或 !$x
字符串 "$x"

结论

我们可以看到上面的方式可以很简短的将表达式转换为我们需要的类型。我们也可以将PHP中的这种转换方式应用到其他语言中来改变表达式的类型。