类型系统

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. 温度转换器:定义温度类型别名,实现摄氏度和华氏度转换
  2. 几何计算:定义点和形状类型,计算面积和周长
  3. 用户管理:定义用户类型和状态枚举,实现用户状态转换

示例解答

// 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 的类型系统!接下来,让我们学习 函数和控制流,了解如何组织和控制程序的执行流程。