为啥 '<' 和 'lt' 运算符在 Perl 中返回不同的结果?

Posted

技术标签:

【中文标题】为啥 \'<\' 和 \'lt\' 运算符在 Perl 中返回不同的结果?【英文标题】:Why do the '<' and 'lt' operators return different results in Perl?为什么 '<' 和 'lt' 运算符在 Perl 中返回不同的结果? 【发布时间】:2009-07-10 13:29:25 【问题描述】:

我只是在学习 Perl 的比较运算符。我尝试了以下代码:-

$foo=291;
$bar=30;

if ($foo < $bar)  
        print "$foo is less than $bar (first)\n"; 


if ($foo lt $bar)  
        print "$foo is less than $bar (second)\n"; 

输出是 291 小于 30(秒)。这是否意味着 lt 运算符总是将变量转换为字符串然后进行比较? Perl 使 lt 运算符的行为不同于 &lt; 运算符的基本原理是什么?

谢谢,

【问题讨论】:

你试过阅读 perl 文档吗?我认为,当您无法自己发现信息时,应该将这个论坛作为最后的手段。 为了加强 ennukiller 的观点,文档在您的计算机上。您应该阅读perldoc perltoc 以了解可用的内容。然后至少浏览大部分这些文档并确保阅读perldoc perlsynperldoc perlvarperldoc perlfuncperldoc perlop。根据您使用的发行版,这些文档的 html 版本可能已经安装在您的计算机上。否则,将这些短语输入 Google 会引导您找到它们。 从什么时候开始,*** 是“最后的手段”?很抱歉这么说,但你们傲慢自大,这是人们只作为最后手段来这里的主要原因。谁希望有人因为提出问题而踩到他们,即使这是他们错过的东西?诚实的疏忽?论坛和问答网站应该是这样的吗?至少人们可以学会不劝阻初学者。并扮演好孩子:) 【参考方案1】:

你的猜测是对的。像lt 这样的字母运算符将变量作为字符串进行比较,而像perlop man page了解更多详情。

基本原理是 Perl 中的标量没有类型,所以如果你不告诉它,Perl 将不知道如何比较两个变量。如果它确实猜到了,那么它有时会出错,这将导致不得不做像' ' + $a &lt; ' ' + $b 这样的事情来强制进行字符串比较,这可能比lt 更糟糕。

也就是说,这是一个可怕的陷阱,它可能会吸引所有刚接触 Perl 的人,并且在使用 less post-modern language 一段时间后回到 Perl 时仍然会抓住我。

【讨论】:

如果 'lt' 只是一个字母运算符,为什么在给定非字母时它不会抱怨。这是否意味着在 perl 中没有类型安全?我读了很多 Bjarne Stroustrup 的采访(根据我老师的建议),他说任何没有类型安全的语言都不好,尽管我不太懂他的语言:-(。 Perl 根本不是类型安全的。它总是假设你知道你在做什么,众所周知,这是非常危险的。例如,想象数组@list = ('a','b','c','d')。假设您尝试使用 length(@list) 查找数组的长度。问题在于长度是用于计算字符串的长度。 Perl 不会抛出错误,而是默默地将数组转换为数字,反映数组的长度 - 4 - 然后它会默默地将这个数字转换为字符串 - “4” - 然后返回字符串的长度 - 1 . 字符串将是比字母更好的术语。想象一下对书名列表进行排序。排序函数将使用 lt。如果你在我的书上运行它,前几个将是 1632 年(埃里克·弗林特)和 1984 年(乔治·奥威尔)。你不希望它出错。 我明白了,谢谢你的解释。由于 Perl 似乎可以将所有内容都转换为字符串,因此它必须擅长处理字符串操作... 不,Perl 不是类型安全的。如果您将某物用作字符串,Perl 将其视为字符串。如果你把它当作一个数字来使用,Perl 会把它当作一个数字来对待。这是好事还是坏事,很大程度上取决于你在做什么。从本质上讲,Perl 是一种用于处理文本的语言,这个特性在这种情况下非常有用。例如,如果您从文件中读取字符串“123”,则不必像在 C 或 Java 中那样将其用作数字之前对其进行解析。【参考方案2】:

由于 Perl 是松散类型的,值可以随时在字符串和整数之间静默转换,Perl 需要两种不同类型的比较运算符来区分整数比较 (&lt;) 和字符串比较 (lt)。如果你只有一个运营商,你会如何区分?

【讨论】:

【参考方案3】:

理由?它是一个字符串运算符。来自“perldoc perlop”:

Binary "lt" returns true if the left argument is stringwise less than the right argument.

如果这不是你想要的,请不要使用它。

【讨论】:

是的,但真正的问题是为什么 Perl 有字符串和数字运算符,而许多其他语言没有。 有些人会这样做。例如,Common Lisp 有大量的相等运算符,包括数字、字符和字符串。 Perl 不是 C、C#、C++、Basic 或 Java。【参考方案4】:

lt 按词法比较值(即按 ASCII/UNICODE 或语言环境顺序),&lt; 按数字比较值。 Perl 有这两个运算符的原因相同,"10" + 515 而不是类型错误:它是弱类型的。你必须总是告诉计算机一些明确的东西。强类型语言倾向于使用强制转换来解决歧义,而弱类型语言倾向于使用大量运算符。相当于"10" + 5 的Python(一种强类型语言)是float("10") + 5

【讨论】:

【参考方案5】:

这是否意味着'lt'运算符 总是将变量转换为 字符串然后比较?

是的,请参阅perlop

Perl 的制作原理是什么 'lt' 运算符的行为不同于 '

因为拥有一个数字比较运算符和一个字符串比较运算符比拥有一个 mumble mumble 运算符和另一个相同的 mumble mumble 运算符更有意义。

【讨论】:

以上是关于为啥 '<' 和 'lt' 运算符在 Perl 中返回不同的结果?的主要内容,如果未能解决你的问题,请参考以下文章

使用 cout 和 cin 时,“<<”和“>>”运算符是做啥的,我们为啥要使用它们?

为啥有人会在枚举声明中使用 << 运算符?

运算符表达式和语句 编程练习

为啥在 Ruby 中构建字符串时,铲子运算符 (<<) 优于加号 (+=)?

为啥我们必须重载“<”运算符才能使用 is_permutation 并包含算法

为啥我不能在 std::array< int, 3 > 的指针上使用运算符 [] 来索引值?