第 4 章 类型系统

在 Julia 中,任何值都是有类型的。可见,与值一样,类型也散布在 Julia 程序的每一个角落。

我们都知道,计算机编程语言大体上可以分为两类。一类是以 C、Java、Golang 为代表的静态类型语言,另一个类是以 Python、Ruby、PHP 为代表的动态类型语言。

所谓的静态类型语言是指,在通常情况下,程序中的每一个变量或表达式的类型在编写时就要有所说明,最迟到编译时也要被确定下来。另外,变量的类型是不可以被改变的。或者说,一个变量只能被赋予某一种类型的值。虽然在有的编程语言(如 Golang)中,变量的类型可以被声明为某个接口类型,从而使其值的类型可以不唯一(只要是该接口类型的实现类型即可),但这终归是有一个非常明确的范围的。

动态类型语言与之有着明显的不同。这类语言中的变量的类型是可变的。或者说,变量的类型会随着我们赋予它的值的类型而变化。这种变化可以说是随心所欲的。它给程序带来了极大的灵活性,但同时也带来了很多不稳定的因素。这主要是由于某些操作只能施加在某个或某种类型的值之上。比如,对于数值类型的值才有求和一说。又比如,只有字符类型和字符串类型的值才能进行所谓的拼接。一旦变量所代表的值与将要施加的操作不匹配,那么程序就会出现异常,甚至崩溃。为了谨慎对待此类错误,我们往往不得不在程序中添加很多额外的错误检测和处理代码。这无疑会加重我们的心智负担。

那些静态类型语言的编译器可以帮助我们检查程序中绝大多部分的类型错误。同时,固化类型的变量也可以让程序跑得更快。不过,这肯定会让我们在写程序时多编写一些代码,包括对变量类型进行声明的代码,以及对不同类型的值实现同一种操作的代码。后一种代码可以被称为多态性代码。

如果多态性代码可以由编程语言提供的一些工具简化,而不用我们完全手动编写,那么就可以说这种编程语言是支持多态的。绝大多数动态类型语言都是支持多态的。其代码几乎都可以自动地成为多态性代码。这也主要得益于其变量类型的可变性。而一些静态类型语言也可以通过一些手段(比如方法重载和泛型)在一定程度上支持多态。