类型系统初探
学习目标
通过本集的学习,你将能够:
- 理解类型的基本概念
- 区分强类型和弱类型
- 区分静态类型和动态类型
- 理解类型安全的重要性
1. 什么是类型?
1.1 类型的定义
类型是对数据的分类,定义了数据可以进行的操作。
类型的作用:
- 规定数据的取值范围
- 定义可以进行的操作
- 防止无意义的操作
- 提供文档1.2 常见类型
基本类型:
- int: 整数
- float: 浮点数
- bool: 布尔值
- char: 字符
- string: 字符串
复合类型:
- 数组/列表
- 结构体/对象
- 函数类型2. 强类型 vs 弱类型
2.1 强类型
强类型语言严格限制类型之间的转换。
Python(强类型):
x = 42
y = "hello"
x + y # TypeError: unsupported operand type(s)
Rust(强类型):
let x: i32 = 42;
let y: &str = "hello";
x + y // 编译错误2.2 弱类型
弱类型语言允许更多的隐式类型转换。
JavaScript(弱类型):
let x = 42;
let y = "hello";
x + y // "42hello"
PHP(弱类型):
$x = 42;
$y = "3";
$x + $y // 452.3 对比
强类型:
- Python, Java, C#, Rust, Haskell
- 更少的隐式转换
- 更早发现错误
- 更安全
弱类型:
- JavaScript, PHP, Perl
- 更多的隐式转换
- 更灵活
- 更容易出bug3. 静态类型 vs 动态类型
3.1 静态类型
静态类型在编译时检查类型。
Java(静态类型):
int x = 42; // 必须声明类型
x = "hello"; // 编译错误
Rust(静态类型):
let x: i32 = 42;
x = "hello"; // 编译错误3.2 动态类型
动态类型在运行时检查类型。
Python(动态类型):
x = 42 // 不需要声明类型
x = "hello" // 可以改变类型
JavaScript(动态类型):
let x = 42;
x = "hello";3.3 类型推断
一些静态类型语言支持类型推断。
Rust(类型推断):
let x = 42; // 推断为 i32
let y = 3.14; // 推断为 f64
TypeScript(类型推断):
let x = 42; // 推断为 number
let y = "hello"; // 推断为 string3.4 对比
静态类型:
- Java, C++, C#, Rust, TypeScript
- 编译时检查
- 更早发现错误
- 更好的性能
- 更多类型注解
动态类型:
- Python, JavaScript, Ruby, PHP
- 运行时检查
- 更灵活
- 更少类型注解
- 更快的开发4. 类型安全
4.1 什么是类型安全?
类型安全指语言防止类型错误的能力。
类型安全的好处:
- 防止崩溃
- 防止数据损坏
- 提高可靠性
- 更容易维护4.2 内存安全
类型安全通常与内存安全相关。
C(不安全):
int x = 42;
int *p = &x;
p[100] = 0; // 缓冲区溢出,可能崩溃
Rust(安全):
let x = 42;
let p = &x;
// 无法进行不安全的操作5. 实用案例
5.1 案例1:TypeScript 的静态类型
TypeScript:
function add(a: number, b: number): number {
return a + b;
}
add(1, 2); // 3
add("1", "2"); // 编译错误!5.2 案例2:Rust 的类型安全
Rust:
fn divide(a: i32, b: i32) -> Option<i32> {
if b == 0 {
None
} else {
Some(a / b)
}
}
// 必须显式处理 None
match divide(10, 2) {
Some(result) => println!("{}", result),
None => println!("Cannot divide by zero"),
}6. 自测问题
- 什么是类型?
- 强类型和弱类型的区别是什么?
- 静态类型和动态类型的区别是什么?
- 什么是类型安全?
- 类型推断有什么好处?
7. 下集预告
下一集我们将学习表达式与语句!
参考资料
- 《程序设计语言:概念与构造》
- 《类型和程序设计语言》