Carbon数组与切片 #

一、数组概述 #

数组是固定大小的同类型元素集合。Carbon数组在编译时确定大小,存储在连续内存中。

二、数组创建 #

2.1 数组字面量 #

carbon
// 指定大小和类型
var arr1: [i32; 5] = (1, 2, 3, 4, 5);

// 类型推断
var arr2 = (1, 2, 3, 4, 5);  // 推断为 [i32; 5]

// 空数组
var empty: [i32; 0] = ();

2.2 默认值初始化 #

carbon
// 所有元素初始化为0
var zeros: [i32; 5] = [i32; 5]();

// 所有元素初始化为指定值
var filled: [i32; 5] = [i32; 5](42);  // (42, 42, 42, 42, 42)

2.3 重复初始化 #

carbon
// 重复模式
var repeated: [i32; 5] = [i32; 5](1, 2);  // (1, 2, 1, 2, 1)

三、数组访问 #

3.1 索引访问 #

carbon
var arr: [i32; 5] = (10, 20, 30, 40, 50);

var first: i32 = arr[0];   // 10
var third: i32 = arr[2];   // 30
var last: i32 = arr[4];    // 50

// 负索引(从末尾)
var last2: i32 = arr[-1];  // 50
var second_last: i32 = arr[-2];  // 40

3.2 边界检查 #

carbon
var arr: [i32; 5] = (1, 2, 3, 4, 5);

// 安全访问
var val: Optional(i32) = arr.Get(10);
if (val.HasValue()) {
  Print("{0}", val.Value());
} else {
  Print("索引越界");
}

3.3 修改元素 #

carbon
var arr: [i32; 5] = (1, 2, 3, 4, 5);

arr[0] = 100;
arr[2] = 300;

Print("{0}", arr[0]);  // 100

四、数组切片 #

4.1 切片语法 #

carbon
var arr: [i32; 10] = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

var slice1: [i32] = arr[2..5];   // (2, 3, 4)
var slice2: [i32] = arr[5..];    // (5, 6, 7, 8, 9)
var slice3: [i32] = arr[..5];    // (0, 1, 2, 3, 4)
var slice4: [i32] = arr[..];     // (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

4.2 切片类型 #

carbon
// 动态大小切片
var slice: [i32] = arr[2..5];

// 切片是数组的视图
arr[2] = 100;
Print("{0}", slice[0]);  // 100

4.3 切片操作 #

carbon
var slice: [i32] = arr[2..8];

var len: i32 = slice.Length();    // 6
var first: i32 = slice.First();   // 第一个元素
var last: i32 = slice.Last();     // 最后一个元素

五、动态数组 #

5.1 创建动态数组 #

carbon
// 空动态数组
var vec: [i32] = ();

// 带初始容量
var vec2: [i32] = [i32](10);

// 从数组创建
var vec3: [i32] = (1, 2, 3, 4, 5);

5.2 添加元素 #

carbon
var vec: [i32] = ();

vec.Push(1);
vec.Push(2);
vec.Push(3);

vec.Append((4, 5, 6));

Print("{0}", vec.Length());  // 6

5.3 删除元素 #

carbon
var vec: [i32] = (1, 2, 3, 4, 5);

var last: i32 = vec.Pop();     // 删除并返回最后一个
vec.RemoveAt(0);               // 删除指定索引
vec.Clear();                   // 清空

5.4 插入元素 #

carbon
var vec: [i32] = (1, 3, 5);

vec.Insert(1, 2);  // 在索引1处插入2
// vec = (1, 2, 3, 5)

vec.InsertRange(3, (4, 5));
// vec = (1, 2, 3, 4, 5, 5)

六、数组操作 #

6.1 查找 #

carbon
var arr: [i32; 5] = (10, 20, 30, 40, 50);

// 查找元素
var index: i32 = arr.Find(30);  // 2
var not_found: i32 = arr.Find(100);  // -1

// 查找满足条件的元素
var idx: i32 = arr.FindIf(fn (x: i32) -> bool { return x > 25; });  // 2

6.2 包含检查 #

carbon
var arr: [i32; 5] = (1, 2, 3, 4, 5);

var has_three: bool = arr.Contains(3);  // true
var has_ten: bool = arr.Contains(10);   // false

6.3 排序 #

carbon
var arr: [i32; 5] = (3, 1, 4, 1, 5);

// 升序排序
arr.Sort();  // (1, 1, 3, 4, 5)

// 降序排序
arr.SortDescending();  // (5, 4, 3, 1, 1)

// 自定义排序
arr.Sort(fn (a: i32, b: i32) -> bool { return a > b; });

6.4 反转 #

carbon
var arr: [i32; 5] = (1, 2, 3, 4, 5);

arr.Reverse();  // (5, 4, 3, 2, 1)

6.5 填充 #

carbon
var arr: [i32; 5] = ();

arr.Fill(42);  // (42, 42, 42, 42, 42)

七、数组遍历 #

7.1 for循环 #

carbon
var arr: [i32; 5] = (1, 2, 3, 4, 5);

for (item in arr) {
  Print("{0}", item);
}

7.2 带索引遍历 #

carbon
var arr: [i32; 5] = (10, 20, 30, 40, 50);

for (i, item in arr.Enumerate()) {
  Print("arr[{0}] = {1}", i, item);
}

7.3 迭代器 #

carbon
var arr: [i32; 5] = (1, 2, 3, 4, 5);
var iter = arr.Iter();

while (true) {
  match (iter.Next()) {
    case Some(value) => Print("{0}", value);
    case None => break;
  }
}

八、多维数组 #

8.1 二维数组 #

carbon
var matrix: [[i32; 3]; 3] = (
  (1, 2, 3),
  (4, 5, 6),
  (7, 8, 9)
);

var val: i32 = matrix[1][2];  // 6

// 遍历
for (row in matrix) {
  for (item in row) {
    Print("{0} ", item);
  }
  Print("");
}

8.2 三维数组 #

carbon
var cube: [[[i32; 3]; 3]; 3] = (
  (
    (1, 2, 3),
    (4, 5, 6),
    (7, 8, 9)
  ),
  (
    (10, 11, 12),
    (13, 14, 15),
    (16, 17, 18)
  ),
  (
    (19, 20, 21),
    (22, 23, 24),
    (25, 26, 27)
  )
);

var val: i32 = cube[1][2][0];  // 16

九、数组算法 #

9.1 Map #

carbon
var arr: [i32; 5] = (1, 2, 3, 4, 5);

var squared: [i32] = arr.Map(fn (x: i32) -> i32 { return x * x; });
// (1, 4, 9, 16, 25)

9.2 Filter #

carbon
var arr: [i32; 10] = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

var evens: [i32] = arr.Filter(fn (x: i32) -> bool { return x % 2 == 0; });
// (2, 4, 6, 8, 10)

9.3 Reduce #

carbon
var arr: [i32; 5] = (1, 2, 3, 4, 5);

var sum: i32 = arr.Reduce(0, fn (a: i32, b: i32) -> i32 { return a + b; });
// 15

9.4 链式操作 #

carbon
var arr: [i32; 10] = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

var result: i32 = arr.Iter()
  .Filter(fn (x: i32) -> bool { return x % 2 == 0; })
  .Map(fn (x: i32) -> i32 { return x * x; })
  .Take(3)
  .Sum();
// 4 + 16 + 36 = 56

十、数组与函数 #

10.1 数组作为参数 #

carbon
fn Sum(arr: [i32]) -> i32 {
  var total: i32 = 0;
  for (item in arr) {
    total += item;
  }
  return total;
}

Sum((1, 2, 3, 4, 5));  // 15

10.2 返回数组 #

carbon
fn Range(start: i32, end: i32) -> [i32] {
  var result: [i32] = ();
  for (i in start..end) {
    result.Push(i);
  }
  return result;
}

var nums: [i32] = Range(0, 10);

10.3 数组引用 #

carbon
fn Modify(arr: [i32]&) {
  arr[0] = 100;
}

var arr: [i32; 5] = (1, 2, 3, 4, 5);
Modify(arr);
Print("{0}", arr[0]);  // 100

十一、最佳实践 #

11.1 选择合适的类型 #

carbon
// 固定大小:使用数组
var days_in_week: [String; 7] = ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun");

// 动态大小:使用动态数组
var user_inputs: [String] = ();

11.2 避免越界 #

carbon
// 使用安全访问
var arr: [i32; 5] = (1, 2, 3, 4, 5);

match (arr.Get(index)) {
  case Some(value) => Print("{0}", value);
  case None => Print("索引越界");
}

11.3 预分配容量 #

carbon
// 知道大概大小时预分配
var vec: [i32] = [i32](1000);
for (i in 0..1000) {
  vec.Push(i);
}

十二、总结 #

本章我们学习了:

  1. 数组创建:字面量、默认值、重复初始化
  2. 数组访问:索引访问、边界检查、修改元素
  3. 数组切片:切片语法、切片操作
  4. 动态数组:添加、删除、插入元素
  5. 数组操作:查找、排序、反转、填充
  6. 多维数组:二维、三维数组
  7. 数组算法:Map、Filter、Reduce

接下来让我们学习Carbon的结构体!

最后更新:2026-03-27