为什么我们可以在python的程序生命周期中使变量指向不同类型的值,但不是在swift中? 这适用于python:
var x = 0;
x = "zero";
迅速抛出错误:
def shift(a, i, j, dir, n, fill=0, inplace=False):
out = a
if not inplace:
out = a.copy()
if dir == 'down':
if n < 0:
return shift(out, i, j, 'up', -n, fill=fill, inplace=True)
n = min(n, a.shape[0] - i)
out[i+n:, j] = a[i:a.shape[0] - n, j]
out[i:i+n, j] = fill
elif dir == 'up':
if n < 0:
return shift(out, i, j, 'down', -n, fill=fill, inplace=True)
n = min(n, i+1)
out[:i+1-n, j] = a[n:i+1, j]
out[i+1-n:i+1, j] = fill
elif dir == 'right':
if n < 0:
return shift(out, i, j, 'left', -n, fill=fill, inplace=True)
n = min(n, a.shape[1] - j)
out[i, j+n:] = a[i, j:a.shape[1] - n]
out[i, j:j+n] = fill
elif dir == 'left':
if n < 0:
return shift(out, i, j, 'right', -n, fill=fill, inplace=True)
n = min(n, j+1)
out[i, :j+1-n] = a[i, n:j+1]
out[i, j+1-n:j+1] = fill
else:
raise ValueError('Unknown direction "{}".'.format(dir))
return out
这种行为与强/弱类型概念或静态/动态概念相关吗?
答案 0 :(得分:2)
与C和Lisp等语言相比,Python和Swift都是强类型的。值可以具有的每种类型都以语言表示,并且如果不执行明确标记为“不安全”的操作,则无法将值解释为不同类型。
与Haskell,Rust和大多数ML变体等语言相比,Python和Swift都是弱类型的。有很多东西可以在类型系统中有用地表达,但不是,最明显的是I / O流的变化 - 你写入的文件与写入之前的文件是同一个文件。
对于静态与动态,这些都是严重超载的术语。您可以争论“动态类型”的哪个定义是最佳定义,但这并不能让您随处可见;重要的是语言之间的差异,无论你如何标记它们都存在。
在两种语言中,值都是(强烈)键入的。但在Python中,变量是无类型名称;在Swift中,变量是包含值的类型化位置。
在Python中,不仅可以,而且惯用于在运行时进行ad-hoc多态,也就是“鸭子打字”;在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
等)。 / p>