Skip to Content

结构体(Struct)

struct 是值语义的复合类型:赋值与传参拷贝整体,改副本不动原件。适合小而自足的数据,如坐标、配置项。

声明与构造

struct Point { public var x: int = 0; public var y: int = 0; public func Show() -> string => $"({x}, {y})"; } struct Pair { public val a: string; public val b: string; init(a: string, b: string) { self.a = a; self.b = b; } }

构造走 new:无构造器的结构体可以直接 new Point(),得到全零值实例;带构造器的必须按签名给实参:

val p = new Point(); print(p.Show()); val q = new Point() { x: 3, y = 4 }; print(q.Show()); val pr = new Pair("甲", "乙");
(0, 0) (3, 4)

对象初始化器 { 字段: 值 }(: 或 = 均可)在构造后逐字段赋值。声明里带初始化器的字段以声明值为起点,其余为类型零值。

值语义

val q = new Point() { x: 3, y: 4 }; var r = q; r.x = 99; print(q.x, r.x);
3 99

r = q 是整体值拷贝,之后两个变量相互独立。这是 struct 与 class 的核心区别:同一行代码放到类上,两边都会变成 99。

容器里的值语义

结构体进容器也保持值语义:从下标读出的是副本,改副本不写回。唯一的例外是下标位直写字段的形式,它定位到容器元素本身:

var xs = new list<Point>(); xs.Add(new Point() { x: 1 }); xs[0].x = 5; print(xs[0].x); var p = xs[0]; p.x = 9; print(xs[0].x, p.x);
5 5 9

xs[0].x = 5 写进容器;var p = xs[0] 先拷出副本,之后的 p.x = 9 只改副本。

嵌套 struct 里的引用类型字段(类引用、容器等)拷的仍是引用本身,指向同一对象。

字段与方法

  • 字段三种绑定:val(不可变,声明后每个显式构造器必须赋值)、var(可变)、const(编译期常量)。无修饰符的字段默认 private;
  • 方法首参写 self(或裸 self),体内直接用字段名访问自身成员;
  • 主构造器形态 struct Name(args) { } 把参数提升为 private val 字段,省去手写 init。

构造器委托

多个构造器之间用 : init(...) 委托,避免复制赋值逻辑:

struct Gauge { public val id: int; public var hits: int = 0; init(id: int) { self.id = id; } init() : init(0) { } } val c = new Gauge(7); print(c.id, c.hits); val c0 = new Gauge(); print(c0.id);
7 0 0

主构造器形态 struct Gauge(id: int) 把参数提升为 private val 字段,适合纯数据聚合,需要逻辑时写显式 init。

with:非破坏性更新

不可变数据结构靠 with 派生新值,不改动原实例。with 可以链式叠加,每级产一个新副本:

struct Point3 { public var x: int = 0; public var y: int = 0; public var z: int = 0; } val q = new Point() { x: 3, y: 4 }; val moved = q with { x: 10 }; print(q.Show(), moved.Show()); val p3 = new Point3() { x: 1, y: 2, z: 3 }; val stepped = p3 with { x: 10 } with { y: 20 }; print(stepped.x, stepped.y, stepped.z); val half = new Point3() { z: 9 } with { y: 5 }; print(half.x, half.y, half.z);
(3, 4) (10, 4) 10 20 3 0 5 9

初始化器缺的字段落类型零值(half 的 x 是 0),with 再逐级补。with 也支持链式与嵌套块,见向量与颜色的同款语义。

注意

  • 泛型结构体 struct Box<T> { }、协议实现 struct Tag impl Greeter、约束 where T: ... 都可与 struct 组合;
  • 构造器可声明 fail 子句,此时 new Gauge(args) 是可失败表达式,调用点须消费,见失败;
  • 结构体没有继承,行为复用走协议与混入。
最后更新于 2026年10月9日