不像其他语言中一个变量只能存放一个特定类型的值(字符串、浮点数、对象),Perl 依赖 操作符的上下文来决定如何对值进行解释(value_contexts)。如果你将数字作为字符串, Perl 将尽最大努力将该数字转换为字符串(反之亦然)。这个过程就是 强制转换。
植根于设计,Perl 就试图按你的意思办事(DWIM 代表 do what I mean),虽然你必须对 你的意图进行较为具体的描述。
布尔强制转换发生于测试某值 为真性 的时候 为真性和真假性有些类似,设想你 斜着眼睛说“啊,那是真的,但是……”,就是 if
或 while
语句中的测试条件。数 值 0 是假。未定义值是假。空字符串和字符串 '0'
是假。然而字符串 '0.0'
和 '0e'
是 真。
所有其他的值是真的,包括惯用语字符串 '0 but true'
。对于诸如有着字符串和数值 两面的标量这种情况(dualvars),Perl 5 选择字符串部分作为检查布尔真假的依据。 '0 but true'
在数值上下文中求值得零,但不是一个空字符串,因此它在布尔上下文 中求值得真。
字符串强制转换发生于使用字符串操作符之时,例如比较(eq
和 cmp
,比方说)、拼 接、split
、substr
以及正则表达式。它也发生在将某值作为哈希键时。未定义值字 符串化得到空字符串,但会引发 “use of uninitialized value(使用未初始化值)” 的警告。 数值 字符串化 得到包含其值的字符串,就是说,值 10
字符串化得到字符串 10
, 如此你便可以用 split
将某数值分割成组成它的各个数字:
数值强制转换发生于使用数值比较操作符(诸如 ==
和 <=>
)、进行数学计算操作以 及将某值作为数组或列表的下标时。未定义值 数值化 得零,虽然这会产生一个“Use of uninitialized value(使用未初始化的值)”的警告。不以数值部分开头的字符串数值化为零,并产生“Argument isn't numeric(参数不是数值)” 的警告。以数值字面值中允许出现的字符开头的字符串将数值化为对应的值, 就是说 10 leptons leaping
数值化为 10
,同样地,6.022e23 moles marauding
数值化为 6.022e23
。
核心模块 Scalar::Util
包含一个名为 looks_like_number()
的函数,它使用和 Perl 5 语法一样的语法分析规则从字符串中提取数字。
在某些的情况下,将一个值作为引用对待将使该值 转变为 一个引用。这个自生 (autovivification)的过程对于嵌套数据结构来说比较有用。它发生在当你对 非引用进行解引用操作时:
虽然上例中的哈希从未包含对应 Bradley
和 Jack
的值,Perl 5 热心地为这 些值创建了哈希引用,接着将以 id
为键的键值对赋值给它们。
Perl 5 对值的内部存储机制允许每个值拥有字符串化和数值化的结果 这是一种简化,但 残酷的现实真的很残酷。字符串化一个数值并不将数值替换为字符串。取而代之的是,它将 字符串化后的值作为对数值的补充 附着 到该值上。类似的操作还发生于数值化一个字符 串值时。
你几乎不必知道发生了这种转换────如果传闻证据可信的话,也许十年内会有个一两次。
Perl 5 也许会偏向于使用某种形式的转换。如果一个值拥有一个缓存了的、但不是你 期望的表示方式,依赖于隐式的转换可能会产生令人惊讶的结果。你几乎不必明确提出 你的期望,但是明白这种缓存确实存在,你可以对某些奇怪的情况做出诊断。
对数值和字符串值的缓存允许你使用一个“罕见但有用”的特性,称为 双重变量, 或者说一个同时拥有数值和字符串表示的值。核心模块 Scalar::Util
提供了一个名为 dualvar()
的函数,它允许你创建一个拥有两种不同形式的值:
Hey! The above document had some coding errors, which are explained below:
- Around line 5:
-
A non-empty Z<>
- Around line 19:
-
A non-empty Z<>
- Around line 23:
-
Deleting unknown formatting code N<>
- Around line 52:
-
A non-empty Z<>
- Around line 100:
-
A non-empty Z<>
- Around line 104:
-
Deleting unknown formatting code N<>
- Around line 117:
-
A non-empty Z<>