集合类型
Fleet 提供了丰富的集合类型来存储和操作数据。本章详细介绍数组、映射、元组等集合类型的使用方法。
📋 目录
📊 数组 (Array)
数组基础
fn main() {
// 数组字面量
let numbers = [1, 2, 3, 4, 5];
let names = ["Alice", "Bob", "Charlie"];
// 指定类型的数组
let scores: [int; 5] = [95, 87, 92, 78, 88];
// 重复元素数组
let zeros = [0; 10]; // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
print("First number: " + numbers[0]);
print("Array length: " + numbers.len());
}
数组操作
fn main() {
var fruits = ["apple", "banana", "orange"];
// 访问元素
print("First fruit: " + fruits[0]);
print("Last fruit: " + fruits[fruits.len() - 1]);
// 修改元素
fruits[1] = "grape";
print("Modified: " + fruits[1]);
// 数组方法
print("Length: " + fruits.len());
print("Is empty: " + fruits.is_empty());
print("Contains apple: " + fruits.contains("apple"));
}
数组遍历
fn main() {
let numbers = [10, 20, 30, 40, 50];
// 基本遍历
loop num in numbers {
print("Number: " + num);
}
// 带索引遍历
loop (index, value) in numbers.enumerate() {
print("Index " + index + ": " + value);
}
// 范围遍历
loop i in 0..numbers.len() {
print("numbers[" + i + "] = " + numbers[i]);
}
}
数组切片
fn main() {
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 切片操作
let slice1 = numbers[2..5]; // [3, 4, 5]
let slice2 = numbers[..3]; // [1, 2, 3]
let slice3 = numbers[7..]; // [8, 9, 10]
let slice4 = numbers[..]; // 完整数组的副本
print("Slice 1: " + slice1);
print("Slice 2: " + slice2);
}
多维数组
fn main() {
// 二维数组
let matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
// 访问二维数组元素
print("Element at (1,1): " + matrix[1][1]); // 5
// 遍历二维数组
loop (i, row) in matrix.enumerate() {
loop (j, value) in row.enumerate() {
print("matrix[" + i + "][" + j + "] = " + value);
}
}
}
🗂️ 映射 (Map)
映射基础
fn main() {
// 映射字面量
let scores = map{
"Alice": 95,
"Bob": 87,
"Charlie": 92,
};
// 空映射
let empty_map = map{};
// 访问元素
print("Alice's score: " + scores["Alice"]);
// 注意:get() 方法目前可能还未完全实现
// 以下是概念性示例
print("Alice's score: " + scores["Alice"]);
}
映射操作
fn main() {
var inventory = map{
"apples": 50,
"bananas": 30,
};
// 插入/更新
inventory["oranges"] = 25;
inventory["apples"] = 60; // 更新现有值
// 删除
inventory.remove("bananas");
// 检查存在性
if inventory.contains_key("apples") {
print("We have apples!");
}
// 映射信息
print("Size: " + inventory.len());
print("Is empty: " + inventory.is_empty());
}
映射遍历
fn main() {
let student_grades = map{
"Alice": 'A',
"Bob": 'B',
"Charlie": 'A',
"David": 'C',
};
// 遍历键值对
loop (name, grade) in student_grades {
print(name + " got grade " + grade);
}
// 只遍历键
loop name in student_grades.keys() {
print("Student: " + name);
}
// 只遍历值
loop grade in student_grades.values() {
print("Grade: " + grade);
}
}
嵌套映射
fn main() {
let company = map>{
"engineering": map{
"Alice": "senior Developer",
"Bob": "junior Developer",
},
"marketing": map{
"Charlie": "Marketing Manager",
"Diana": "Content Creator",
},
};
// 访问嵌套数据
let alice_role = company["engineering"]["Alice"];
print("Alice's role: " + alice_role);
// 遍历嵌套结构
loop (department, employees) in company {
print("Department: " + department);
loop (name, role) in employees {
print(" " + name + ": " + role);
}
}
}
📦 元组 (Tuple)
元组基础
fn main() {
// 元组字面量
let point = (10, 20);
let person = ("Alice", 30, true);
let empty = ();
// 访问元组元素
print("X coordinate: " + point.0);
print("Y coordinate: " + point.1);
print("Name: " + person.0);
print("Age: " + person.1);
print("Is student: " + person.2);
}
元组解构
fn get_name_age() -> (str, int) {
return ("Bob", 25);
}
fn main() {
// 解构赋值
let (name, age) = get_name_age();
print("Name: " + name + ", Age: " + age);
// 部分解构
let (first, _) = ("Hello", "World"); // 忽略第二个元素
print("First: " + first);
// 嵌套解构
let nested = ((1, 2), (3, 4));
let ((a, b), (c, d)) = nested;
print("a=" + a + ", b=" + b + ", c=" + c + ", d=" + d);
}
元组作为函数参数
fn distance(p1: (int, int), p2: (int, int)) -> f64 {
let dx = p2.0 - p1.0;
let dy = p2.1 - p1.1;
return sqrt(dx * dx + dy * dy);
}
fn main() {
let point1 = (0, 0);
let point2 = (3, 4);
let dist = distance(point1, point2);
print("Distance: " + dist); // 5.0
}
🔢 集合 (Set)
集合基础
fn main() {
// 集合字面量
let numbers = set{1, 2, 3, 4, 5};
let words = set{"hello", "world", "fleet"};
// 空集合
let empty_set = set{};
// 集合操作
print("Size: " + numbers.len());
print("Contains 3: " + numbers.contains(3));
print("Is empty: " + numbers.is_empty());
}
集合操作
fn main() {
var fruits = set{"apple", "banana"};
// 添加元素
fruits.insert("orange");
fruits.insert("apple"); // 重复元素不会被添加
// 删除元素
fruits.remove("banana");
// 集合运算
let set1 = set{1, 2, 3, 4};
let set2 = set{3, 4, 5, 6};
let union = set1.union(set2); // {1, 2, 3, 4, 5, 6}
let intersection = set1.intersection(set2); // {3, 4}
let difference = set1.difference(set2); // {1, 2}
print("Union: " + union);
print("Intersection: " + intersection);
print("Difference: " + difference);
}
📝 字符串 (String)
字符串基础
fn main() {
// 字符串字面量
let greeting = "Hello, Fleet!";
let multiline = """
This is a
multiline string
""";
// 字符串操作
print("Length: " + greeting.len());
print("Is empty: " + greeting.is_empty());
print("Uppercase: " + greeting.to_uppercase());
print("Lowercase: " + greeting.to_lowercase());
}
字符串操作
fn main() {
let text = "Hello, World!";
// 子字符串
let sub = text.substring(0, 5); // "Hello"
print("Substring: " + sub);
// 查找
let index = text.find("World");
match index {
Option::Some(i) => print("Found at index: " + i),
Option::None => print("Not found"),
}
// 替换
let replaced = text.replace("World", "Fleet");
print("Replaced: " + replaced); // "Hello, Fleet!"
// 分割
let parts = text.split(", ");
loop part in parts {
print("Part: " + part);
}
}
字符串格式化
fn main() {
let name = "Alice";
let age = 30;
let height = 5.6;
// 字符串插值
let message = "Name: {name}, Age: {age}, Height: {height:.1}";
print(message);
// 格式化函数
let formatted = format("Hello, {}! You are {} years old.", name, age);
print(formatted);
}
🔄 集合操作
映射操作
fn main() {
let numbers = [1, 2, 3, 4, 5];
// map - 转换每个元素
let doubled = numbers.map(|x| x * 2);
print("Doubled: " + doubled); // [2, 4, 6, 8, 10]
// filter - 过滤元素
let evens = numbers.filter(|x| x % 2 == 0);
print("Evens: " + evens); // [2, 4]
// reduce - 聚合操作
let sum = numbers.reduce(0, |acc, x| acc + x);
print("Sum: " + sum); // 15
}
链式操作
fn main() {
let words = ["hello", "world", "fleet", "language"];
let result = words
.filter(|word| word.len() > 4)
.map(|word| word.to_uppercase())
.collect();
print("Result: " + result); // ["HELLO", "WORLD", "FLEET", "LANGUAGE"]
}
排序和搜索
fn main() {
var numbers = [5, 2, 8, 1, 9, 3];
// 排序
numbers.sort();
print("Sorted: " + numbers); // [1, 2, 3, 5, 8, 9]
// 自定义排序
var people = [
("Alice", 30),
("Bob", 25),
("Charlie", 35),
];
people.sort_by(|a, b| a.1.compare(b.1)); // 按年龄排序
print("Sorted by age: " + people);
// 二分查找
let index = numbers.binary_search(5);
match index {
Option::Some(i) => print("Found 5 at index: " + i),
Option::None => print("5 not found"),
}
}
🎯 高级集合操作
集合转换
fn main() {
// 数组转集合
let arr = [1, 2, 2, 3, 3, 3];
let unique_set = arr.to_set();
print("Unique elements: " + unique_set); // {1, 2, 3}
// 集合转数组
let back_to_array = unique_set.to_array();
print("Back to array: " + back_to_array);
// 映射转数组
let map_data = map{"a": 1, "b": 2};
let keys = map_data.keys().to_array();
let values = map_data.values().to_array();
print("Keys: " + keys);
print("Values: " + values);
}
嵌套集合操作
fn main() {
let matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
// 展平二维数组
let flattened = matrix.flatten();
print("Flattened: " + flattened); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
// 转置矩阵
let transposed = matrix.transpose();
print("Transposed: " + transposed);
// 按行求和
let row_sums = matrix.map(|row| row.sum());
print("Row sums: " + row_sums); // [6, 15, 24]
}
📊 性能考虑
选择合适的集合类型
// 频繁随机访问 - 使用数组
let data = [1, 2, 3, 4, 5];
let value = data[2]; // O(1)
// 键值查找 - 使用映射
let lookup = map{"key": 42};
let value = lookup["key"]; // 平均 O(1)
// 唯一性检查 - 使用集合
let unique = set{1, 2, 3};
let exists = unique.contains(2); // 平均 O(1)
// 有序数据 - 使用排序数组或有序映射
let sorted_data = [1, 2, 3, 4, 5];
let index = sorted_data.binary_search(3); // O(log n)
内存优化
fn main() {
// 预分配容量
var large_array = Array::with_capacity(1000);
// 使用迭代器避免中间集合
let result = (0..1000)
.filter(|x| x % 2 == 0)
.map(|x| x * x)
.take(10)
.collect();
print("Result: " + result);
}
📚 最佳实践
集合选择指南
- 数组 - 固定大小,频繁索引访问
- 映射 - 键值对存储,快速查找
- 集合 - 唯一元素,成员检查
- 元组 - 固定数量的异构数据
性能建议
- 预分配容量 - 避免频繁重新分配
- 使用迭代器 - 延迟计算,减少内存使用
- 选择合适的算法 - 考虑时间复杂度
- 避免不必要的复制 - 使用引用和借用
代码风格
- 一致的命名 - 使用描述性名称
- 适当的注释 - 解释复杂的集合操作
- 错误处理 - 检查边界和空集合
- 测试覆盖 - 测试边界情况