类型视角下的编程语言

关于强/弱/静态/动态类型语言的说法

关于编程语言中强/弱/静态/动态类型语言的划分,网络上存在很多互相矛盾的信息,这里做一个梳理。

数据类型的意义是指定变量中数据的长度和处理方式。

简洁说法:强/弱类型指的是语言类型系统的类型检查的严格程度;静态/动态类型区分的是变量与类型的绑定方法。

网上可以找到两张分类图,左边来自Mahdi Yusuf,右边来自biancheng.net

我个人认为C应该是弱类型,因为有void*这种万能指针做转换(不会有警告),并且允许弱类型写法通过编译(不同类型指针转换只有警告而已)。

C++从某种意义上说类型应该比C更强,因为禁止了不同类型指针之间的相互赋值(赋值给void*例外,反之不行),但是类型转换运算符使C++类型转换更自由了,说它更弱也可以。

侯捷老师的《STL源码解析》第60页(2.2.6节)说这种技巧(见如下代码)在强类型语言如Java中行不通,在非强类型语言如C++中十分普遍。

1
2
3
4
5
union obj
{
union obj *free_list_link;
char client_data[1];
}

还有一种说法是面临与类型不匹配的运算时,弱类型尝试提供帮助,临时转换值让其符合当前运算。以JS为例。强类型遇到这种情况会报错。

1
2
3
4
var a = 5;
var b = "5";
console.log(a+b);
// 输出是10

哥舒夜带刀的说法是,类型的划分省略了太多信息,区分以下三对概念更重要:

  1. 弱类型检查与强类型检查

    类型检查的目标是捕获与类型有关的错误,能保证不存在与类型有关的不可捕获错误的编程语言,称为具有强类型检查;反之称为具有弱类型检查。

  2. 动态类型检查与静态类型检查

    静态类型检查是指在编译阶段进行的类型检查,动态类型检查是在执行阶段进行的类型检查。

    解释型语言自己没有静态类型检查,但可以借助外部工具做到。

    用编译型、解释型来分类编程语言已经过时了。就拿Java来说,先编译为字节码再由JVM解释执行,看上去是半解释半编译,JIT技术还会把热点代码直接编译为机器码。

  3. 标识符的动态类型绑定与静态类型绑定

    按标识符与特定类型的数据绑定后,重新绑定的约束条件划分。


类型视角下的编程语言
https://reddish.fun/posts/Article/programming-languages-​​from-a-type-perspective/
作者
bit704
发布于
2023年4月10日
许可协议