想要回到标题描述的问题,首先需要搞清楚两对概念:
- 静态类型/动态类型:依据 Type Checker 的时间来分类:静态类型是指编译时变量的类型即可确定;动态类型是指运行时变量的类型才可知晓。
- 强类型/弱类型:依据是否存在隐式类型转换分类:强类型不存在隐式类型转换;弱类型存在隐式类型转换。
其实,在学术上,静态类型/动态类型、强类型/弱类型二者并不存在明确的定义,如果追求地在细致一些,还可以依据错误类型来分类,例如依据 数组越界后是报错还是继续执行 来划分为强、弱类型。
依据上述描述,可以对语言来进行简单的分类:
- Rust: 静态、强类型
let mut a = 1;
a = '1'; // error, 静态类型(运行时变量类型无法转化)
1 + '1'; // error, 强类型(不存在隐式类型转换)
既然存在隐式类型转换,那么也肯定存在强制类型转换。强制类型转换俗称 cast, 在 Rust 中的语法为
let b = 1 as f64;
.
- Cpp: 静态、弱类型
c++ 是弱类型可能不符合一些人的预期。
int a[10] = {1,2,3};
a = 10; // error, 静态类型
1 + '1'; // 正常执行,弱类型
- JavaScript: 动态、弱类型
let a = 1;
a = 'abc' // 正常执行,动态类型
1 + '1' // 正常执行,输出 '11', 弱类型
- Python3: 动态、强类型
a = 1
a = '1' # 正常执行,动态类型
1 + '1' # error, 强类型
另外,Python 中存在可能让人迷惑的一点:诸如 1 + True
是可行的(其结果为 2),这可能让人误以为它是弱类型(1
是 int, 而 True
是 bool),但实际上,python 中 bool 类继承自 int 类,对于 bool 实例而言,本身也是一种 int, 这与 python 内实现方式有关,并没有发生隐式类型转换。