Skip to Content

数组(Array)

T[] 是定长数组:长度固定、元素可读写、赋值与传参共享同一份存储。array<T> 是它的具名别名,两写法同型。

创建

三条路径:无注解的集合字面量、带注解的目标构造、按长度分配:

val xs = [1, 2, 3]; print(xs, xs.Length, xs.Count); val buf = new int[3]; buf[2] = 7; print(buf, buf[0]); val names = new string?[2]; names[0] = "甲"; print(names);
[1, 2, 3] 3 3 [null, null, 7] 0 [甲, null]

无注解的 [1, 2, 3] 推断为数组,这是集合字面量的默认形态。new T[n] 分配 n 个零值槽:数值槽读 0、布尔槽读 False,引用元素请写可空元素 new T?[n],或用集合字面量、工厂形填充。

工厂形分配

new T[n](f) 用函数值 f 逐槽填充,绕开零值分配——每槽恰好调用一次,各槽独立不共享:零参形每槽得 f(),单 int 参的索引形槽 i 得 f(i)。f 不允许 fail / uses / async,返回类型须可赋元素类型:

val boxes = new Box[2](() => new Box()); val squares = new int[5](i => i * i); print(boxes); print(squares);
[Main.Box, Main.Box] [0, 1, 4, 9, 16]

泛型函数里同样受约束:new T[n](T 是类型参数)编译期直接拒,也需要使用工厂形创建实例:

func Fill<T>(make: func() -> T, n: int) -> T[] { return new T[n](make); } val xs = Fill<int>(() => 0, 3); // [0, 0, 0] val cs = Fill<Box>(() => new Box(), 2); // 两个独立实例

引用共享

数组赋值、传参不拷贝,两边看到同一个对象:

val a = xs; a[1] = 99; print(xs[1]);
99

a 与 xs 是同一个数组,改 a[1] 就是改 xs[1]。要独立副本可以使用 ToList() 再转回来。

读写与成员

xs[0] = 9; print(xs[1], xs.Contains(99)); val alias: array<int> = xs; print(alias[1], alias.Contains(99)); alias.Set(2, 30); print(alias, alias.ToSortedList(), alias.Reversed());
99 True 99 True [9, 99, 30] [9, 30, 99] [30, 99, 9]

索引器读写之外,方法面有 Get(i) / Set(i, v) / Contains(v) / ToList() / Reversed()(反转拷贝) / ToSortedList()(排序拷贝)。Length 与 Count 都是属性。

切片恒产新数组

xs[起..止] 从数组或列表切出一段,结果是独立的新数组,与源不再共享:

print(xs[1..3]); val tail = xs[1..3]; tail[0] = -1; print(xs[1], tail[0]);
[99, 30] 99 -1

对 tail[0] 的写不影响原数组,反过来原数组后续变化也不反映进切片。区间越界或倒序一律裁剪(xs[2..1] 取空),只有单索引越界才报错。

与 List 互转

数组与列表没有隐式互转,互赋报 MS3101。显式转换是 lst.ToArray() 与 arr.ToList(),两边都是新容器:

val ls: list<int> = [4, 5]; ls.Add(6); val back = ls.ToArray(); back[0] = 40; print(ls[0], back[0]); val again = back.ToList(); again.Add(1); print(again, again.Count);
4 40 [40, 5, 6, 1] 4

集合字面量的目标构造仍然成立:目标类型是 list<int> 就产列表,是 int[] 就产数组。

注意

  • for n in xs 直接遍历元素。
  • int[] 与 array<int> 随意混用,两种写法等价,建议只选择其中一种使用。
  • 数组判等是引用同一性,按内容比较用 ContentEquals,见判等与哈希。
最后更新于 2026年10月10日