类型系统
Fleet 拥有强大的静态类型系统,提供编译时类型安全保证和智能类型推断。本章将深入介绍 Fleet 的类型系统。
🎯 类型系统概述
Fleet 的类型系统具有以下特点:
- 静态类型检查 - 编译时验证类型安全
- 类型推断 - 减少显式类型注解
- 零成本抽象 - 类型信息不影响运行时性能
- 内存安全 - 防止空指针和缓冲区溢出
🔢 基础类型
整数类型
Fleet 提供了完整的整数类型系列:
fn integer_types() {
// 有符号整数
let i8_val: i8 = -128; // -128 到 127
let i16_val: i16 = -32768; // -32,768 到 32,767
let i32_val: i32 = -2147483648; // -2^31 到 2^31-1
let i64_val: i64 = -9223372036854775808; // -2^63 到 2^63-1
// 无符号整数
let u8_val: u8 = 255; // 0 到 255
let u16_val: u16 = 65535; // 0 到 65,535
let u32_val: u32 = 4294967295; // 0 到 2^32-1
let u64_val: u64 = 18446744073709551615; // 0 到 2^64-1
// 架构相关整数
let int_val: int = 42; // 默认有符号整数(通常 i64)
let uint_val: uint = 42; // 默认无符号整数(通常 u64)
}
浮点数类型
fn floating_point_types() {
let f32_val: f32 = 3.14; // 32位浮点数
let f64_val: f64 = 3.141592653589793; // 64位浮点数
let default_float = 2.718; // 默认为 f64
// 科学计数法
let large = 1.23e10; // 12,300,000,000
let small = 1.23e-10; // 0.000000000123
let negative_exp = -4.56e-7; // -0.000000456
}
字符和字符串类型
fn character_and_string_types() {
// 字符类型
let unicode_char: rune = '🚀'; // Unicode 字符(32位)
let ascii_char: rune = 'A'; // ASCII 字符
let byte_char: byte = b'A'; // 单字节字符(8位)
// 字符串类型
let greeting: str = "Hello, Fleet!";
let empty_string: str = "";
let unicode_string: str = "你好,世界!🌍";
// 原始字符串(不转义)
let raw_path: str = r"C:\Users\Name\Documents";
let raw_regex: str = r"\d+\.\d+";
}
布尔类型
fn boolean_type() {
let is_true: bool = true;
let is_false: bool = false;
// 布尔运算
let and_result = true && false; // false
let or_result = true || false; // true
let not_result = !true; // false
// 比较运算产生布尔值
let comparison = 5 > 3; // true
let equality = "hello" == "world"; // false
}
🏗️ 复合类型
元组类型
元组可以组合不同类型的值:
fn tuple_types() {
// 基础元组
let unit: () = (); // 单元类型
let single: (int,) = (42,); // 单元素元组
let pair: (int, str) = (42, "hello"); // 二元组
let triple: (int, str, bool) = (1, "test", true); // 三元组
// 嵌套元组
let nested: ((int, int), str) = ((1, 2), "point");
// 元组访问
let x = pair.0; // 42
let y = pair.1; // "hello"
// 元组解构
let (num, text) = pair;
let (a, b, c) = triple;
}
数组类型
fn array_types() {
// 固定大小数组
let fixed: [int; 5] = [1, 2, 3, 4, 5];
let zeros: [int; 3] = [0; 3]; // [0, 0, 0]
// 动态数组(切片)
let dynamic: [int] = [1, 2, 3, 4, 5];
let empty: [str] = [];
// 数组访问
let first = fixed[0]; // 1
let last = fixed[4]; // 5
// 数组长度
let length = fixed.len(); // 5
}
映射类型
fn map_types() {
// 映射声明
let scores: map = map{
"Alice": 95,
"Bob": 87,
"Charlie": 92,
};
// 空映射
let empty: map = map{};
// 映射操作
let alice_score = scores["Alice"]; // 95
scores["David"] = 88; // 添加新项
// 安全访问
let maybe_score = scores.get("Eve"); // Option
let exists = scores.contains("Bob"); // true
}
🎯 类型推断
Fleet 的类型推断系统可以自动推导大多数类型:
fn type_inference() {
// 编译器可以推断这些类型
let number = 42; // 推断为 int
let pi = 3.14159; // 推断为 f64
let greeting = "Hello"; // 推断为 str
let is_valid = true; // 推断为 bool
// 从函数返回值推断
let result = calculate(); // 推断为函数返回类型
// 从上下文推断
let mut numbers = []; // 初始为空,类型待定
numbers.push(1); // 现在推断为 [int]
numbers.push(2);
// 泛型类型推断
let pairs = [(1, "one"), (2, "two")]; // 推断为 [(int, str)]
}
fn calculate() -> int {
return 42;
}
🔄 类型转换
显式类型转换
fn explicit_conversions() {
// 数值类型转换
let int_val: int = 42;
let float_val: f64 = int_val as f64; // 42.0
let byte_val: u8 = int_val as u8; // 42
// 字符串转换
let num_str = int_val.to_string(); // "42"
let float_str = float_val.to_string(); // "42.0"
// 安全转换(返回 Option)
let parsed_int = "123".parse::(); // Some(123)
let invalid_parse = "abc".parse::(); // None
}
自动类型提升
fn automatic_promotion() {
let small: i32 = 100;
let large: i64 = 1000;
// 自动提升到更大的类型
let result = small + large; // small 自动提升为 i64
// 浮点数提升
let int_num = 42;
let float_num = 3.14;
let mixed = int_num + float_num; // int_num 提升为 f64
}
🏷️ 自定义类型
类型别名
// 为现有类型创建别名
type UserId = int;
type UserName = str;
type Coordinates = (f64, f64);
fn type_aliases() {
let user_id: UserId = 12345;
let name: UserName = "Alice";
let position: Coordinates = (10.5, 20.3);
// 类型别名提高代码可读性
fn get_user(id: UserId) -> UserName {
return "User" + id.to_string();
}
let user = get_user(user_id);
}
结构体类型
// 定义结构体
struct Point {
x: f64,
y: f64,
}
struct Person {
name: str,
age: int,
email: str,
}
fn struct_types() {
// 创建结构体实例
let origin = Point { x: 0.0, y: 0.0 };
let person = Person {
name: "Alice",
age: 30,
email: "alice@example.com",
};
// 访问字段
let x_coord = origin.x;
let person_name = person.name;
// 结构体更新语法
let moved_point = Point { x: 5.0, ..origin };
}
枚举类型
// 基础枚举
enum Status {
Pending,
Approved,
Rejected,
}
// 带数据的枚举
enum Message {
Text(str),
Number(int),
Coordinates(f64, f64),
}
// 泛型枚举
enum Option {
Some(T),
None,
}
enum Result {
Ok(T),
Err(E),
}
fn enum_types() {
let status = Status::Pending;
let message = Message::Text("Hello");
let coordinates = Message::Coordinates(10.0, 20.0);
// 模式匹配
match message {
Message::Text(content) => print("Text: " + content),
Message::Number(num) => print("Number: " + num),
Message::Coordinates(x, y) => print("Point: (" + x + ", " + y + ")"),
}
}
🔍 类型检查
编译时检查
Fleet 在编译时进行严格的类型检查:
fn type_checking_examples() {
let number: int = 42;
let text: str = "hello";
// 正确:类型匹配
let sum = number + 10;
let greeting = text + " world";
// 错误:类型不匹配
// let invalid = number + text; // 编译错误
// let wrong: int = "not a number"; // 编译错误
}
类型安全保证
fn type_safety() {
let numbers: [int] = [1, 2, 3, 4, 5];
// 安全的数组访问
if numbers.len() > 0 {
let first = numbers[0]; // 安全
}
// 映射的安全访问
let scores: map = map{"Alice": 95};
match scores.get("Alice") {
Some(score) => print("Alice's score: " + score),
None => print("Alice not found"),
}
}
🎯 最佳实践
1. 合理使用类型推断
// 好的做法:让编译器推断明显的类型
let count = 0;
let name = "Alice";
let is_valid = true;
// 在需要时提供类型注解
let user_id: UserId = parse_id(input);
let coordinates: (f64, f64) = get_location();
2. 使用有意义的类型别名
// 好的做法:提高代码可读性
type Temperature = f64;
type Distance = f64;
type Duration = int;
fn calculate_speed(distance: Distance, time: Duration) -> f64 {
return distance / time as f64;
}
// 避免:过度使用类型别名
// type MyInt = int; // 没有增加语义价值
3. 选择合适的数值类型
// 根据数据范围选择类型
let age: u8 = 25; // 年龄不会超过 255
let population: u64 = 1000000; // 人口数可能很大
let temperature: f32 = 23.5; // 温度精度要求不高
let precise_calc: f64 = 3.141592653589793; // 需要高精度
🎯 练习
尝试以下练习来掌握类型系统:
- 温度转换器:定义温度类型别名,实现摄氏度和华氏度转换
- 几何计算:定义点和形状类型,计算面积和周长
- 用户管理:定义用户类型和状态枚举,实现用户状态转换
示例解答
// 1. 温度转换器
type Celsius = f64;
type Fahrenheit = f64;
fn celsius_to_fahrenheit(c: Celsius) -> Fahrenheit {
return c * 9.0 / 5.0 + 32.0;
}
fn fahrenheit_to_celsius(f: Fahrenheit) -> Celsius {
return (f - 32.0) * 5.0 / 9.0;
}
// 2. 几何计算
struct Point {
x: f64,
y: f64,
}
enum Shape {
Circle(f64), // 半径
Rectangle(f64, f64), // 宽度,高度
Triangle(Point, Point, Point), // 三个顶点
}
fn calculate_area(shape: Shape) -> f64 {
match shape {
Shape::Circle(radius) => 3.14159 * radius * radius,
Shape::Rectangle(width, height) => width * height,
Shape::Triangle(p1, p2, p3) => {
// 使用海伦公式计算三角形面积
// 这里简化为固定值
return 10.0;
},
}
}
// 3. 用户管理
enum UserStatus {
Active,
Inactive,
Suspended,
Deleted,
}
struct User {
id: int,
name: str,
email: str,
status: UserStatus,
}
fn change_user_status(user: User, new_status: UserStatus) -> User {
return User {
status: new_status,
..user
};
}
fn main() {
// 温度转换
let temp_c: Celsius = 25.0;
let temp_f = celsius_to_fahrenheit(temp_c);
print("25°C = " + temp_f + "°F");
// 几何计算
let circle = Shape::Circle(5.0);
let area = calculate_area(circle);
print("Circle area: " + area);
// 用户管理
let user = User {
id: 1,
name: "Alice",
email: "alice@example.com",
status: UserStatus::Active,
};
let suspended_user = change_user_status(user, UserStatus::Suspended);
}
📖 下一步
恭喜你掌握了 Fleet 的类型系统!接下来,让我们学习 函数和控制流,了解如何组织和控制程序的执行流程。