Skip to content

Latest commit

 

History

History
193 lines (126 loc) · 8.18 KB

context_philosophy.pod

File metadata and controls

193 lines (126 loc) · 8.18 KB

上下文

[当阅读这个小节的时候,我意识到 Perl 中的上下文的基础是“用什么操作符”以及“在哪里用它”。 在本小节和 operator_types.pod 中,你决不会直接地说出来。但这是真的。我试图在这个小节的 某处中直接地说出来,但是我还无法决定在哪里已经怎样说,因此这只是一个提议。] 口语中有 上下文 的概念,即某词汇或短语的正确用法和含义由语境所决定。理解一下在口语中的情况, “Please give me one hamburgers!” 中不合适的复数用法 名词的复数形式和数量不符, 听上去就不对,或者 “la gato” 中不正确的性别 冠词为阴性,但是名称为阳性 使得母语人士轻声窃笑。 同样考虑代词 “you” 或者名词 “sheep” ,是单数是复数还得由句子的余下部分决定。

Perl 中的上下文是类似的,这门语言理解对数据数量上的期望同时也知道应该提供什么样的数据。 Perl 将高兴地尝试提供给你恰好合你心意的数据。

Perl 中上下文的每一种类型,都和你所需某操作符结果的个数(零个、一个、或许多个)相对应, 同一个操作符在(不同的上下文中)有着不同的行为。在 Perl 中,如果你要求:“给我零个结果, 我不在乎有没有”或是“给我一个结果”再或是“给我多个结果”,那么一个特定的结构按这些不同的要 求做不同的事情是完全可能的。

同样,特定上下文将你所需明朗化:是数值,是字符串值、或是一个为真或假的值。

如果你打算把 Perl 代码当成一系列独立于环境的单一表达式来读写,那么上下文将会变得十足狡猾。 在一次长时间的调试后,你也许会一拍脑门,发现你对程序上下文的假设是错误的。然而在对上下文 了如指掌后,它们会使你的代码更清晰、更简洁、更灵活。

空、标量和列表上下文

上下文之一掌控着你期望事物的 多少。这就是 数量上下文。这个上下文和英语中“主谓一致” 相当。即使尚未了解这条规则的正式定义,你很有可能理解句子 "Perl are a fun language" 中的错误。 Perl 中的规则是,你所要求事物的数量决定了你得到的。

假设你有一个称为 some_expensive_operation() 的函数 (functions),它进行一昂贵的计算并 产生许多许多结果。如果你直接调用该函数且对返回值不加利用,那么就称你在 空上下文 中调用了 这个函数:

将函数的返回值赋值给单个元素使得函数在 标量上下文 中求值:

将调用函数的结果赋值给一个数组(arrays)或是列表,或者在一个列表中使用该结果,使 得函数在 列表上下文 中求值:

前例的第二行可能看上去有些迷惑,这里的括号给了编译器一点提示:尽管这里只有一个 标量,该赋值应在列表上下文中发生。在语义上等同于将列表中的第一个元素赋值给一个 标量,并将列表的其余部分赋值给一个临时数组,随即丢弃该数组。除非真的发生(类似于 后例的)数组赋值:

在列表上下文中对函数或表达式────除赋值外────求值,可能造成迷惑性结果。列表会把列表 上下文散播到其所包含的表达式中。下列对 some_expensive_operation() 的调用都发生于 列表上下文:

上例 expensive_operation 位于列表上下文,因为它被赋值到一个哈希中,而哈希赋值需要一 键值对列表,导致在哈希赋值内的所有表达式在列表上下文中求值。

后一个例子通常使期望该调用为标量上下文的新手程序员吃惊。相反,这是列表上下文,因为该上 下文为哈希赋值所强制。使用 scalar 操作符可以迫使其在标量上下文求值:

数值、字符串及布尔上下文

另一类型的上下文决定了 Perl 如何理解某块数据────不是你要 多少 数据,而是数据的意义。 你也许早已觉察到 Perl 可以灵活地指出你所有的是数字还是字符串并在按需在两者之间转换。这就是 值上下文,有助解释 Perl 是如何做这些事情的。不必明确声明(至少是跟踪)某变量包含(或产 生自某函数)的数据的 类型,作为交换,Perl 提供了特定类型的上下文,由它们告知编译器在某项 操作期间如何对待一个给定的值。

假设你想比较两个字符串的内容。eq 操作符能告诉你这些字符串中是否包含相同的信息:

明明知道 字符串内容不同,但是比较结果却是相同时,你可能会感到莫名其妙:

eq 操作符通过强制 字符串上下文,按字符串对待它的操作数。== 操作符则强制 数值上下文。 示例代码出错的原因在于,两个字符串在用作数字时候的值是 0numeric_coercion)。

布尔上下文 发生在当你在条件语句中使用某值时。在前面的例子中,if 语句在布尔上下文中求出 eq== 操作的结果。

Perl 会尽最大努力将值强制转换成正确的类型 (coercion),并依赖于所用的操作符。一定要针对你所需的 上下文使用正确的操作符。

在极少数情况下,没有合适类型的操作符存在,你也许需要明确地强制上下文。强制数值上下文,在变量前加零。 强制字符串上下文,将变量和空字符串拼接起来。强制布尔上下文,使用双重否定操作符。

大体上说,相比数量上下文,类型上下文较易理解和识别。一旦你理解它们的存在,并知道什么操作符提供什 么上下文 (operator_types),你很少会因为它们而犯错。

POD ERRORS

Hey! The above document had some coding errors, which are explained below:

Around line 5:

A non-empty Z<>

Around line 9:

Deleting unknown formatting code N<>

Deleting unknown formatting code N<>

Around line 33:

A non-empty Z<>

Around line 136:

A non-empty Z<>