-5

为什么我们可以在 python 程序的生命周期中将变量指向不同类型的值,但不能在 swift 中?这适用于python:

x = 0
x = "zero"

迅速抛出错误:

var x = 0;
x = "zero";

这种行为是否与强/弱类型概念或静态/动态概念相关?

4

1 回答 1

2

与 C 和 Lisp 等语言相比,Python 和 Swift 都是强类型的。值可以具有的每种类型都用语言表示,如果不做明确标记为“不安全”的事情,就无法将值解释为不同的类型。

与 Haskell、Rust 和大多数 ML 变体等语言相比,Python 和 Swift 都是弱类型的。可以想象,在类型系统中可以有用地表达许多东西,但最明显的是 I/O 流的突变——您写入的文件与写入之前的文件相同。


至于静态与动态,这些是严重超载的术语。您可以争论“动态类型”的哪个定义是最好的定义,但这并不能帮助您;重要的是语言之间的差异,无论您如何标记它们,它们都存在。

在这两种语言中,值都是(强)类型的。但是在 Python 中,变量是无类型的名称;在 Swift 中,变量是保存值的类型化位置。

在 Python 中,在运行时进行临时多态性(即“鸭子类型”)不仅是可能的,而且是惯用的;这在 Swift 中是不正确的。

两种语言都有类型注释和类型推断规则。在 Swift 中,编译器会应用这些规则并在无法验证所有内容的类型时拒绝您的代码。在 Python 中,编译器会忽略注释并且什么都不推断,如果你想对代码进行类型检查,你必须使用像 Mypy 这样的可选工具。

Python 和 Swift 都至少支持某种形式的带有动态调度的 OO。也就是说,即使在 Swift 中,一个Base变量也可能包含一个Derived值(这里忽略关于值与引用语义的问题)。然而,Python 采用 Smalltalk 风格,通过反射有效地查找它,而 Swift 采用 C++ 风格,使用静态编译的表在运行时查找方法调用。除了 Swift 有一个针对 Objective C 对象的逃生路径,它处理 Smalltalk 风格的调度。


部分由于上述一些差异,Swift 的运行时类型系统与其静态类型系统完全一样强大,但 Python 更强大。在 Python 中运行时可能存在无法用静态类型语言表达的类型区别。这是否意味着 Python 比 Swift 更具表现力,或者 Swift 比 Python 更安全,这是一个有趣的争论问题。(当然,其中许多区别在 Haskell 的类型系统中是可以表达的,所以你可以说 Haskell 比 Swift 更具表达性,比 Python 更安全。)

另一个与强与弱或静态与动态无关的重要区别是,Swift 鼓励某种程度的类型驱动编程——例如,在代数类型上进行模式匹配之类的事情是惯用的。另一方面,在 Python 中,不鼓励进行各种类型的转换。并不是你做不到(尽管它没有像 Swift 那样好的语法糖),而是它几乎总是被认为更 Pythonic 来做其他事情(无论是 OO @singledispatch,等等)。

于 2018-03-12T18:40:13.097 回答