Skip to content

Latest commit

 

History

History
137 lines (92 loc) · 5.44 KB

coercion.pod

File metadata and controls

137 lines (92 loc) · 5.44 KB

强制转换

不像其他语言中一个变量只能存放一个特定类型的值(字符串、浮点数、对象),Perl 依赖 操作符的上下文来决定如何对值进行解释(value_contexts)。如果你将数字作为字符串, Perl 将尽最大努力将该数字转换为字符串(反之亦然)。这个过程就是 强制转换

植根于设计,Perl 就试图按你的意思办事(DWIM 代表 do what I mean),虽然你必须对 你的意图进行较为具体的描述。

布尔强制转换

布尔强制转换发生于测试某值 为真性 的时候 为真性和真假性有些类似,设想你 斜着眼睛说“啊,那是真的,但是……”,就是 ifwhile 语句中的测试条件。数 值 0 是假。未定义值是假。空字符串和字符串 '0' 是假。然而字符串 '0.0''0e'

所有其他的值是真的,包括惯用语字符串 '0 but true'。对于诸如有着字符串和数值 两面的标量这种情况(dualvars),Perl 5 选择字符串部分作为检查布尔真假的依据。 '0 but true' 在数值上下文中求值得零,但不是一个空字符串,因此它在布尔上下文 中求值得真。

字符串强制转换

字符串强制转换发生于使用字符串操作符之时,例如比较(eqcmp,比方说)、拼 接、splitsubstr 以及正则表达式。它也发生在将某值作为哈希键时。未定义值字 符串化得到空字符串,但会引发 “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)的过程对于嵌套数据结构来说比较有用。它发生在当你对 非引用进行解引用操作时:

虽然上例中的哈希从未包含对应 BradleyJack 的值,Perl 5 热心地为这 些值创建了哈希引用,接着将以 id 为键的键值对赋值给它们。

强制转换的缓存

Perl 5 对值的内部存储机制允许每个值拥有字符串化和数值化的结果 这是一种简化,但 残酷的现实真的很残酷。字符串化一个数值并不将数值替换为字符串。取而代之的是,它将 字符串化后的值作为对数值的补充 附着 到该值上。类似的操作还发生于数值化一个字符 串值时。

你几乎不必知道发生了这种转换────如果传闻证据可信的话,也许十年内会有个一两次。

Perl 5 也许会偏向于使用某种形式的转换。如果一个值拥有一个缓存了的、但不是你 期望的表示方式,依赖于隐式的转换可能会产生令人惊讶的结果。你几乎不必明确提出 你的期望,但是明白这种缓存确实存在,你可以对某些奇怪的情况做出诊断。

双重变量

对数值和字符串值的缓存允许你使用一个“罕见但有用”的特性,称为 双重变量, 或者说一个同时拥有数值和字符串表示的值。核心模块 Scalar::Util 提供了一个名为 dualvar() 的函数,它允许你创建一个拥有两种不同形式的值:

POD ERRORS

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