10

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

i = 5
print i + " "

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

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

我希望有其他方式(在python中我可以在没有任何转换的情况下做到这一点,但C#会要求我将int转换为字符串或将字符串转换为int)。

只是为了强调,我不是在问哪种语言更好,我很好奇以这种方式实现语言的原因是什么。

4

6 回答 6

23

你说得对,这里有些奇怪。奇怪的是,这+意味着任何一种语言的字符串连接!与完全意味着“连接”的奇怪相比,是否+可以将 int 连接到字符串上是一个小问题。+

我不知道首先允许+使用哪种语言来表示字符串连接,但是这种错误功能已经一遍又一遍地重复,以至于现在我们通常甚至没有注意到它有多奇怪。让我们列出一些普通加法的属性,看看字符串是否符合要求。

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

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

我不常这么说,但C 说得对。字符串连接运算符应该就是:连接。在 C"X" "Y"中表示"XY". 如果将两个字符串文字并排放置,它们将连接成第三个。

于 2013-10-23T23:04:27.873 回答
9

这并不是静态与动态类型的真正领域。相反,它是类型与类型(至少根据维基百科在描述编程语言时也碰巧使用的一些常用术语)。C# 和 Python 都是强类型的(根据该定义)。

不幸的是,所有这些概念都不是黑白的,而是灰度的,并且定义不明确。然而,结果是语言执行类型检查的强度以及它执行的检查存在细微差别

碰巧的是,在您的特定情况下,C# 重载operator +了字符串和数字(​​实际上是任意对象),而 Python 没有。在这种情况下,这可以说使 Python 稍微严格一些。

于 2013-10-23T21:26:19.660 回答
9

这不是一个真正的静态/动态问题,而是一个语言设计理念的问题。

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

但是,当您拥有其中一个时,会发生什么?它是尝试将字符串转换为数字,还是将数字转换为字符串?对于任何进行过任何编程的人来说,两者都是完全合理的行为,但是由于不同的语言对如何发生这种情况有不同的规则,你可能会做出与其他人不同的假设,具体取决于你有哪些语言经验已经。

Python 的指导原则之一是“显式优于隐式”(import this),因此它让您明确说明您想要哪种行为。如何?当然,通过将字符串或数字转换为所需的类型。然后它们都是字符串或都是数字,并且行为很明显。

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

于 2013-10-23T21:52:53.773 回答
3

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

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

在我看来,这更多是 .NET Framework 工作的结果,而不是其他任何东西。

于 2013-10-23T21:46:07.160 回答
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。我建议明确说明你的类型转换,即使只是转换为字符串,因为边缘情况会让你发疯。

于 2013-10-23T22:02:44.577 回答
1

动态类型在这里并没有真正发挥作用,两种语言都理解 i 是一个 int 而 " " 是一个字符串。不同之处在于 C# 有一个函数 + 接受 (int,string) 参数,而 Python 没有。

于 2013-10-23T21:28:59.673 回答