有许多语言可以进行类型自动转换,而许多语言则不会。我应该提前说,我认为这不是一个好主意,而且我更喜欢我的语言中更有原则的行为,但有些人更喜欢自动转换的方便和不冗长。
Perl
Perl 是一种可以进行类型自动转换的语言的示例,这里有一个非常有趣的示例,它显示了这在什么时候可能会非常令人困惑。
print "bob" eq "bob";
print "nancy" eq "nancy";
print "bob" == "bob";
print "nancy" == "nancy";
上面的程序打印 1(为真)三次,而不是四次。为什么不是第四个?好吧,“南希”不是==“南希”。为什么不?因为 == 是数值相等运算符。eq 用于字符串相等。正在比较字符串,就像您在 eq 中所做的那样,但在 == 中,它们会自动转换为数字。“鲍勃”等于多少?当然是零。任何没有数字作为前缀的字符串都被解释为零。出于这个原因,“鲍勃”==“克里斯”是真的。为什么不是“nancy”==“nancy”?为什么“南希”不是零?因为这被读作“不是数字”的“nan”。NaN 不等于另一个 NaN。我个人觉得这很令人困惑。
Javascript
Javascript 是另一个可以进行类型自动转换的语言示例。
'5' - 3
这个表达式的结果是什么?2!很好。
'5' + 3
那个结果是什么?8?错误的!这是'53'。
使困惑?好的。哇 Javascript,这么好的约定,很有意义。这是一系列基于自动转换类型的非常有趣的 Javascript 评估。
为什么会有人这样做!?
在看过一些精心挑选的恐怖故事之后,您可能会问自己,为什么那些聪明到发明了全世界最流行的两种编程语言的人会做出如此愚蠢的事情。我不喜欢类型自动转换,但公平地说,这是有争议的。这不是纯粹的错误。考虑以下 Haskell 表达式:
length [1,2,3,4] / 2
这等于什么?2?2.0?没有!由于类型错误,它无法编译。length 返回一个 Int 并且您不能将其分开。您必须通过调用 fromIntegral 将长度显式转换为分数才能使其工作。
fromIntegral (length [1,2,3,4]) / 2
如果您在程序中使用整数和浮点数进行大量数学运算,那肯定会很烦人。但我更愿意理解为什么 nancy 不等于 nancy 但实际上 chris 等于 bob。
快乐的媒介?
方案只有一种数字类型。它会自动转换浮点数、分数和整数,并按照您的预期处理它们。它将允许您在不显式转换的情况下划分列表的长度,因为它知道您的意思。但是不,它永远不会秘密地将字符串转换为数字。字符串不是数字。这很愚蠢。;)
你的例子
至于你的例子,很难说它是否合乎逻辑。令人困惑,是的。我的意思是你在这里堆栈溢出不是吗?我认为你得到 3 的原因要么是 -3 被解释为像罗斯所说的那样,作为 2 的恭维中的一个单位并且是一个更高的数字,或者因为 min 的结果是 -3 然后它变成了unsigned int 去掉负数。问题是您要求将结果放入无符号整数中,但结果是否定的。所以我会说它所做的在类型自动转换的上下文中是合乎逻辑的,但是类型自动转换是令人困惑的。据推测,您不必在整个地方进行显式类型转换,并且有时会以这种奇怪的行为为它付出代价。