在对任何编程语言的讨论中,争议较大的一个问题就是类型模型。类型决定可以使用哪些种类的工具,并影响到应用程序的设计。很多开发人员将类型与生产率或可维护性联系起来(我就是其中的一个)。典型的 Java 开发人员通常都特别乐于维护 Java 语言的类型模型的地位,强调 Java 语言可采用更好的开发工具,在编译时捕捉某些种类的 bug(例如类型不兼容和拼写错误),以及性能等方面的优势。
如果您想理解一种新的编程语言,甚至一系列语言,那么通常应该从类型策略着手。在本文中,您将看到 Java 之外的一些语言中的类型模型。我首先简要介绍任何语言设计者在类型模型中必须考虑的一些决策,着重介绍静态类型和动态类型的一些不同的决策。我将展示一些不同极端的例子 —— Objective Caml 中的静态类型和 Ruby 中的动态类型。我还将谈到 Java 语言的类型限制,以及如何突破 Java 类型的限制快速编程。
类型策略
至少可以从三个角度来看待类型:
静态类型还是动态类型,这取决于何时 实施类型模型。静态类型语言在编译时实施类型。而动态类型语言通常基于一个对象的特征在运行时实施类型。
强类型还是弱类型,这取决于如何 实施类型模型。强类型严格地实施类型,如果发现有违反类型规则的情况,则会抛出运行时或编译时错误。而弱类型则留有更多的余地。极端情况下,弱类型语言(例如 Assembler)允许将任意数据类型赋给另一种类型(不管这种赋值是否有意义)。静态类型的语言既可以有强类型,也可以有弱类型;而动态类型系统通常是强类型的,但也不完全是。
显式类型还是隐式类型,这取决于语言如何确定一个给定对象的类型。显式类型语言要求声明每个变量和每个函数参数。而隐式类型语言则根据语言中的语法和结构线索来确定对象的类型。静态类型语言通常是显式类型的,但也不完全是;而动态类型语言几乎都是隐式类型的。
下面两个例子很好地阐释了其中两个角度的内涵。假设您编译下面这段 Java 代码:
class Test {
public static void test(int i) {
String s = i;
}
}
会收到如下错误消息:
Test.java:3: incompatible types
found : int
required: java.lang.String
String s = i;
^
1 error
执行以下 Ruby 代码:
1 + "hello"
会收到以下错误消息:
TypeError: String can't be coerced into Fixnum
from (irb):3:in '+'
from (irb):3
这两种语言都倾向于强类型,因为当您试图使用一个它们期望之外的类型结构的对象时,它们都会抛出错误消息。Java 类型策略在编译时给出错误消息,因为它执行静态类型检查。而 Ruby 则是在运行时给出错误消息,因为 Ruby 支持动态类型。换句话说,Java 在编译时将对象绑定到类型。而 Ruby 则是在运行时每当更改对象的时候将对象绑定到类型。由于我是在 Java 代码中,而不是在 Ruby 中声明变量的,因此可以看到 Java 语言的显式类型与 Ruby 的隐式类型的工作方式不同。
在这三个角度中,静态类型与动态类型对于语言的特征有最大的影响,因此接下来我将重点解释这两种策略各自的优点。
静态类型的优点
在静态类型语言中,程序员(通过声明或根据约定)或编译器(根据结构和语法线索)将一种类型指定给一个变量,然后那个类型就不会改变。静态类型通常需要额外的成本,因为静态类型语言(例如 Java 语言)通常是显式类型的。这意味着必须声明所有的变量,然后编译代码。成本也伴随着收益:早期的错误检测。静态类型在最基层为编译器提供多得多的信息。更多信息所带来的好处就是,可以更早地捕捉到某些类型的错误,而动态类型语言只有到运行时才能检测到这些错误。如果您一直等到运行时才捕捉这些 bug,那么其中一些将进入生产环境。也许这正是动态类型语言受到最多指责的一个方面。
| 论坛热门帖子: | [lch203] 写得蛮好的linux学习笔记(10-21) [黑马制造] 学习java的30个目标(10-19) [笑傲股林] 做测试半年了,有点迷茫,应该再学些什么提高自己的测试水平和测试能力呢?(10-19) [udp8589] 大家用google的来吱一声? 用百度的~~也来报道下?(10-18) [沂偌掳兆] 本人总结的一些认为C++比较经典的书籍,希望对大家有用(10-18) |
| TAG标签: | 策略 类型 以外 模型 语言 静态 Java 动态 错误 编译 |
注册
个人空间
