为什么“int + string”在静态类型的C#中是可能的,而在动态类型的Python中却不行?

时间:2013-10-23 21:23:28

标签: c# python types

在学习C#时我发现它很奇怪,动态类型的Python会在以下代码中出现错误:

i = 5
print i + " "

而静态类型的C#通常会进行类似的代码:

int i = 5;
Console.Write(i + " ");

我希望有其他方法(在python中我可以在没有任何强制转换的情况下执行此操作,但C#将要求我将int转换为string或string转换为int)。

只是为了强调,我不是在问什么语言更好,我很好奇这种语言实施背后的原因是什么。

6 个答案:

答案 0 :(得分:23)

你说得对,这里有点奇怪。奇怪的是,+表示两种语言中的字符串连接! +是否可以将int连接到字符串上是一个小点,而奇怪的是+意味着“连接”。

我不知道哪种语言首先允许+用于表示字符串连接,但这种错误一再重复,所以现在我们通常甚至都没有注意到它是多么奇怪。让我们列出正常添加的一些属性,看看字符串是否正常。

  • 添加是可交换的,但字符串连接不是。 x + y!= y + x
  • 添加是关联的,但C#中的字符串连接不是。如果y和z是整数,则(x + y)+ z不必等于x +(y + z)。
  • 加法与逆运算,减法配对,其特性是如果x + y是z则z-y是x。字符串没有这样的操作。
  • 添加具有左右标识,字符串连接也是如此。 (空字符串)。

四分之一不好。字符串连接与添加非常不同,那么它们为什么要共享一个运算符呢?

我不经常这样说,但是 C做对了。字符串连接运算符应该只是:连接。在C "X" "Y"中表示"XY"。如果你把两个字符串文字放在一起,它们会连接成第三个。

答案 1 :(得分:9)

这不是静态与动态类型的区域。相反,它是类型(至少根据一些常用的术语,维基百科也恰好在其编程语言的特征描述中使用)。 C#和Python都是强类型的(根据定义)。

遗憾的是,所有这些概念都不是黑白色,而是灰度级,并且定义不明确。然而,结果是语言执行类型检查的强度有细微差别,检查

恰巧在您的特定情况下,C#会为字符串和数字(​​实际上是任意对象)重载operator +,而Python则不会。在这种情况下,这可能会使Python变得更加严格。

答案 2 :(得分:9)

这不是一个静态/动态的问题,而是语言设计哲学的问题。

在Python中,+被定义为数字的加法和字符串的连接。如果您有一点编程经验,这是非常合理的行为。

但是当你有一个时,会发生什么?它是否尝试将字符串转换为数字,还是将数字转换为字符串?对于任何完成任何编程的人来说,这两者都是完全合理的行为,但由于不同的语言对于这种情况的发生方式有不同的规则,因此根据您使用的语言,您可能会做出与其他人不同的假设。已经

Python的指导原则之一是“显式优于隐式”(import this),因此它可以明确说明您想要的行为。怎么样?当然,通过将字符串或数字转换为所需的类型。然后它们都是字符串或两个数字,行为是显而易见的。

生成的代码更容易阅读(即使你不太了解Python),因为你不必猜测它会做什么。

答案 3 :(得分:3)

对于C#,Int32(int)和ToString()的所有类型都有一个名为almost的方法 - 指针类型在这种情况下是例外。

C#中的String类重载了+运算符,在这种情况下,只调用String.Concat(Object, Object)

在我看来,这更多是.NET Framework工作的结果。

答案 4 :(得分:2)

了解python数据模型(http://docs.python.org/2/reference/datamodel.html#emulating-numeric-types)将为您提供帮助。

执行a + b时,会在幕后将其翻译为a.__add__(b)。这是python支持运算符重载的方式,因为缺少静态类型。

C#允许通过ToString()方法隐式转换为字符串; python没有任何隐式转换的概念。这是有效的,因为ToString()是在每个对象上定义的方法,并且C#具有静态类型,因此当调用者的对象将被转换时,它显而易见。

如果您希望在行动中看到此行为,可以运行以下命令(但不要在生产中执行此操作):

class MyString(str):
    def __add__(self, other):
        """ automatically concatenate other values as strings """
        return super(MyString, self).__add__(str(other))

s = MyString("this is a string")
print s + 1

当然,如果你看一下上面的转换,你就会遇到print 1 + s的问题。我建议明确你的类型转换,即使只是转换为字符串,因为边缘情况会让你发疯。

答案 5 :(得分:1)

动态类型在这里并没有发挥作用,两种语言都理解我是一个int而“”是一个字符串。区别在于C#有一个带有(int,string)参数的函数+,而Python没有。