MIT软件构造Reading
静态检查Static Checking
静态类型与动态类型
我们在编程敲代码的时候,很容易就会不小心敲错字母,从而导致无法识别关键字、变量名称未定义等情况发生。有时候会写关于运算的代码,比如a/b,在实际中b是不可以为0的,但是在程序中需要追踪检查b值变化情况,若b为0,则会出错。
我们手动输入的内容无法保证一定是正确的,因此,程序都需要进行对错误的检查。但是应该在什么时候进行检查呢?
1)在写程序时报错。
2)在编译时报错。
3)在程序运行时报错。
4)不报错
编程语言有类型检查的机制,确保并强制声明的变量的类型(常量,布尔值,数字,变量,数组,对象)与指定的值相匹配,其目的就是为了避免程序发生一些不好的情况。
编程语言按照类型检查可以分为两大类:静态类型 (Static Typing) 和 动态类型 (Dynamic Typing)。静态类型语言在编译时执行类型检查,是基于对程序源代码的分析来验证程序的类型安全性的过程。而动态类型的语言在运行时执行类型检查,验证程序的类型安全性的过程。
例如:
Java是一种静态类型的语言。所有变量的类型在编译时(程序运行之前)都是已知的,因此编译器也可以推导出所有表达式的类型。即若声明变量a和b为int类型,则a+b也为int类型。对于敲错字母导致的错误,许多开发工具提供在编写代码时执行检查操作的服务,在敲入代码时,会有许多错误提示。C++也是一种静态类型的语言,用它编写的源程序必须先进行编译,编译通过才可以进行运行;若编译不通过,则会报错。
Python是一种动态类型语言,这种检查将推迟到运行时(程序运行时)进行。
静态类型是一种特殊的静态检查,这意味着在编译时检查错误。错误是编程的祸根。静态类型可以防止大量的bug影响程序,确切地说,是由于对错误类型的参数执行操作而导致的bug。
检查类型
静态检查,动态检查,不检查
静态检查:在程序运行之前会自动发现该错误。
动态检查:执行代码后会自动发现错误。
不检查:根本无法帮助找到错误。编程人员必须自己注意,否则最终会得到错误的答案。
不可否认的是,静态捕获错误要比动态捕获更好,而动态捕获总比根本不捕获要好。即三者的考虑顺序为静态检查>动态检查>不检查
静态检查可以发现的错误类型:
1.语法错误,例如多余的标点符号或虚假单词。
2.错误的名称,
3.参数数量错误,
4.错误的参数类型,
5.错误的返回类型,
动态检查可以发现的错误类型:
1.语法错误,类似Python这样的动态类型语言也进行这种静态检查。如果您的Python程序出现缩进错误,则会在程序开始运行之前先进行查找。
2.非法参数值。例如,整数表达式x/y只有在y实际上为零时才是错误的。否则它会起作用。因此,在此表达式中,被零除不是静态错误,而是动态错误。
3.无法代表的返回值,即当特定的返回值无法在类型中表示时。
4.超出范围的索引,例如,在字符串上使用负数或太大的索引。
5.在null对象引用上调用方法(null类似于Python None)。
静态检查的优点
1.避免错误。 静态检查通过在运行时捕获类型错误和其他错误来帮助提高安全性。
2. 容易明白。 因为类型在代码中明确声明,所以有助于理解。
3. 准备好进行更改。静态检查可以通过识别需要串联更改的其他位置来更轻松地更改代码。例如,当您更改变量的名称或类型时,编译器会立即在使用该变量的所有位置显示错误,并提醒您也更新它们。
静态检查往往与类型有关,而错误与变量具有的特定值无关。类型是一组值。静态类型保证变量将具有该集合中的某个值,但是直到运行时我们才确切知道它具有哪个值。因此,如果错误仅由某些值引起,例如被零除或超出范围的索引,则编译器将不会对此引发静态错误。动态检查往往涉及由特定值引起的错误。
静态检查和动态检查各自有各自的有点,我们不能简单地就说某一种一定比另外一种好,好不好是根据需要、个人习惯爱好有关的。比如说,习惯边写边纠正、首先保证名称类型等正确,就会觉得静态检查能在编译时就能发现类型上的错误,更早的找到简单错误,方便快速。
总的而言,静态类型,如Java 和 C++,比较适合大型的软件工程项目,简单错误早发现早解决,方便后期进行其他操作。