Skip to content

Commit dbe0044

Browse files
lilhammerfunclaude
andcommitted
docs(struct): add struct initialization section
The original tutorial jumped directly to type inference syntax without covering basic struct initialization, which confused beginners. - Add "struct initialization" section with struct literal syntax - Rewrite "type inference shorthand" section with concrete examples - Update code examples accordingly 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent f8774c8 commit dbe0044

File tree

6 files changed

+290
-39
lines changed

6 files changed

+290
-39
lines changed

course/basic/advanced_type/struct.md

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,26 @@
3737

3838
:::
3939

40+
## 结构体初始化
41+
42+
在声明了结构体类型之后,我们需要创建该类型的实例。Zig 使用 **结构体字面量(struct literal)** 语法来初始化结构体。
43+
44+
结构体字面量的完整语法是 `StructName{ .field1 = value1, .field2 = value2 }`
45+
46+
<<<@/code/release/struct.zig#struct_init_basic
47+
48+
以上代码展示了:
49+
50+
- 使用结构体类型名称 `Point` 加上花括号 `{}` 来创建实例
51+
- 花括号内使用 `.字段名 = 值` 的形式为每个字段赋值
52+
- 字段之间用逗号分隔
53+
54+
:::info 🅿️ 提示
55+
56+
结构体字面量中必须为所有没有默认值的字段提供初始值,否则会产生编译错误。
57+
58+
:::
59+
4060
## 自引用
4161

4262
常见的自引用方式是将结构体自身的指针作为函数的第一个参数,例如:
@@ -79,13 +99,19 @@
7999

80100
:::
81101

82-
## 自动推断
102+
## 类型推断简写
103+
104+
在前面我们学习了结构体字面量的完整语法 `StructName{ .field = value }`。当 Zig 编译器能够从上下文推断出结构体类型时,可以省略类型名称,使用简写语法 `.{ .field = value }`
105+
106+
这种机制被称为**结果位置语义(Result Location Semantics)**
83107

84-
Zig 在使用结构体时支持省略类型声明,此时 Zig 会利用结果位置语义进行类型推断,例如:
108+
<<<@/code/release/struct.zig#struct_init_inferred
85109

86-
<<<@/code/release/struct.zig#auto_reference
110+
在上面的示例中:
87111

88-
_这种基于结果位置语义的推导也适用于结构体自身的方法以及其内部定义的其他类型(此处不指结构体字段)。_
112+
- `pt2` 的类型已经被显式声明为 `Point`,因此编译器可以推断出 `.{ .x = 13, .y = 67 }` 应该是 `Point` 类型
113+
- `origin()` 方法的返回类型已声明为 `Point`,因此返回值可以使用简写
114+
- `printPoint` 函数的参数类型为 `Point`,调用时可以直接传入 `.{ .x = 100, .y = 200 }`
89115

90116
## 泛型实现
91117

course/code/11/struct.zig

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
pub fn main() !void {
22
Struct.main();
3+
StructInitBasic.main();
34
SelfReference1.main();
45
SelfReference2.main();
56
try SelfReference3.main();
6-
AutoReference.main();
7+
StructInitInferred.main();
78
DefaultField.main();
89
EmptyStruct.main();
910
Tuple_.main();
@@ -172,19 +173,63 @@ const SelfReference3 = struct {
172173
// #endregion more_self_reference3
173174
};
174175

175-
const AutoReference = struct {
176+
const StructInitBasic = struct {
176177
pub fn main() void {
177-
// #region auto_reference
178-
const Point = struct { x: i32, y: i32 };
178+
// #region struct_init_basic
179+
const Point = struct {
180+
x: i32,
181+
y: i32,
182+
};
183+
184+
// 使用完整的结构体字面量语法初始化
185+
const pt1 = Point{ .x = 10, .y = 20 };
186+
187+
// 也可以先声明类型,再使用完整语法初始化
188+
const pt2: Point = Point{ .x = 30, .y = 40 };
189+
// #endregion struct_init_basic
179190

180-
const pt: Point = .{
191+
_ = pt1;
192+
_ = pt2;
193+
}
194+
};
195+
196+
const StructInitInferred = struct {
197+
// #region struct_init_inferred
198+
const Point = struct {
199+
x: i32,
200+
y: i32,
201+
202+
// 在方法返回值中使用简写语法
203+
pub fn origin() Point {
204+
return .{ .x = 0, .y = 0 }; // 返回类型已声明为 Point,可推断
205+
}
206+
};
207+
208+
fn printPoint(p: Point) void {
209+
_ = p;
210+
}
211+
212+
pub fn main() void {
213+
// 完整语法:显式指定类型名称
214+
const pt1 = Point{ .x = 10, .y = 20 };
215+
216+
// 简写语法:当类型可推断时,可省略类型名称
217+
const pt2: Point = .{
181218
.x = 13,
182219
.y = 67,
183220
};
184-
// #endregion auto_reference
185221

186-
_ = pt;
222+
// 在方法返回值中使用简写
223+
const pt3 = Point.origin();
224+
225+
// 作为函数参数传递(参数类型已知时可推断)
226+
printPoint(.{ .x = 100, .y = 200 });
227+
228+
_ = pt1;
229+
_ = pt2;
230+
_ = pt3;
187231
}
232+
// #endregion struct_init_inferred
188233
};
189234

190235
// #region linked_list

course/code/12/struct.zig

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
pub fn main() !void {
22
Struct.main();
3+
StructInitBasic.main();
34
SelfReference1.main();
45
SelfReference2.main();
56
try SelfReference3.main();
6-
AutoReference.main();
7+
StructInitInferred.main();
78
DefaultField.main();
89
EmptyStruct.main();
910
Tuple_.main();
@@ -172,19 +173,63 @@ const SelfReference3 = struct {
172173
// #endregion more_self_reference3
173174
};
174175

175-
const AutoReference = struct {
176+
const StructInitBasic = struct {
176177
pub fn main() void {
177-
// #region auto_reference
178-
const Point = struct { x: i32, y: i32 };
178+
// #region struct_init_basic
179+
const Point = struct {
180+
x: i32,
181+
y: i32,
182+
};
183+
184+
// 使用完整的结构体字面量语法初始化
185+
const pt1 = Point{ .x = 10, .y = 20 };
186+
187+
// 也可以先声明类型,再使用完整语法初始化
188+
const pt2: Point = Point{ .x = 30, .y = 40 };
189+
// #endregion struct_init_basic
190+
191+
_ = pt1;
192+
_ = pt2;
193+
}
194+
};
195+
196+
const StructInitInferred = struct {
197+
// #region struct_init_inferred
198+
const Point = struct {
199+
x: i32,
200+
y: i32,
179201

180-
const pt: Point = .{
202+
// 在方法返回值中使用简写语法
203+
pub fn origin() Point {
204+
return .{ .x = 0, .y = 0 }; // 返回类型已声明为 Point,可推断
205+
}
206+
};
207+
208+
fn printPoint(p: Point) void {
209+
_ = p;
210+
}
211+
212+
pub fn main() void {
213+
// 完整语法:显式指定类型名称
214+
const pt1 = Point{ .x = 10, .y = 20 };
215+
216+
// 简写语法:当类型可推断时,可省略类型名称
217+
const pt2: Point = .{
181218
.x = 13,
182219
.y = 67,
183220
};
184-
// #endregion auto_reference
185221

186-
_ = pt;
222+
// 在方法返回值中使用简写
223+
const pt3 = Point.origin();
224+
225+
// 作为函数参数传递(参数类型已知时可推断)
226+
printPoint(.{ .x = 100, .y = 200 });
227+
228+
_ = pt1;
229+
_ = pt2;
230+
_ = pt3;
187231
}
232+
// #endregion struct_init_inferred
188233
};
189234

190235
// #region linked_list

course/code/14/struct.zig

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
pub fn main() !void {
22
Struct.main();
3+
StructInitBasic.main();
34
SelfReference1.main();
45
SelfReference2.main();
56
try SelfReference3.main();
6-
AutoReference.main();
7+
StructInitInferred.main();
78
DefaultField.main();
89
EmptyStruct.main();
910
Tuple_.main();
@@ -214,19 +215,63 @@ const SelfReference3 = struct {
214215
// #endregion more_self_reference3
215216
};
216217

217-
const AutoReference = struct {
218+
const StructInitBasic = struct {
218219
pub fn main() void {
219-
// #region auto_reference
220-
const Point = struct { x: i32, y: i32 };
220+
// #region struct_init_basic
221+
const Point = struct {
222+
x: i32,
223+
y: i32,
224+
};
225+
226+
// 使用完整的结构体字面量语法初始化
227+
const pt1 = Point{ .x = 10, .y = 20 };
228+
229+
// 也可以先声明类型,再使用完整语法初始化
230+
const pt2: Point = Point{ .x = 30, .y = 40 };
231+
// #endregion struct_init_basic
232+
233+
_ = pt1;
234+
_ = pt2;
235+
}
236+
};
237+
238+
const StructInitInferred = struct {
239+
// #region struct_init_inferred
240+
const Point = struct {
241+
x: i32,
242+
y: i32,
221243

222-
const pt: Point = .{
244+
// 在方法返回值中使用简写语法
245+
pub fn origin() Point {
246+
return .{ .x = 0, .y = 0 }; // 返回类型已声明为 Point,可推断
247+
}
248+
};
249+
250+
fn printPoint(p: Point) void {
251+
_ = p;
252+
}
253+
254+
pub fn main() void {
255+
// 完整语法:显式指定类型名称
256+
const pt1 = Point{ .x = 10, .y = 20 };
257+
258+
// 简写语法:当类型可推断时,可省略类型名称
259+
const pt2: Point = .{
223260
.x = 13,
224261
.y = 67,
225262
};
226-
// #endregion auto_reference
227263

228-
_ = pt;
264+
// 在方法返回值中使用简写
265+
const pt3 = Point.origin();
266+
267+
// 作为函数参数传递(参数类型已知时可推断)
268+
printPoint(.{ .x = 100, .y = 200 });
269+
270+
_ = pt1;
271+
_ = pt2;
272+
_ = pt3;
229273
}
274+
// #endregion struct_init_inferred
230275
};
231276

232277
// #region linked_list

course/code/15/struct.zig

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
pub fn main() !void {
22
Struct.main();
3+
StructInitBasic.main();
34
SelfReference1.main();
45
SelfReference2.main();
56
try SelfReference3.main();
6-
AutoReference.main();
7+
StructInitInferred.main();
78
DefaultField.main();
89
EmptyStruct.main();
910
Tuple_.main();
@@ -214,19 +215,63 @@ const SelfReference3 = struct {
214215
// #endregion more_self_reference3
215216
};
216217

217-
const AutoReference = struct {
218+
const StructInitBasic = struct {
218219
pub fn main() void {
219-
// #region auto_reference
220-
const Point = struct { x: i32, y: i32 };
220+
// #region struct_init_basic
221+
const Point = struct {
222+
x: i32,
223+
y: i32,
224+
};
225+
226+
// 使用完整的结构体字面量语法初始化
227+
const pt1 = Point{ .x = 10, .y = 20 };
228+
229+
// 也可以先声明类型,再使用完整语法初始化
230+
const pt2: Point = Point{ .x = 30, .y = 40 };
231+
// #endregion struct_init_basic
232+
233+
_ = pt1;
234+
_ = pt2;
235+
}
236+
};
237+
238+
const StructInitInferred = struct {
239+
// #region struct_init_inferred
240+
const Point = struct {
241+
x: i32,
242+
y: i32,
221243

222-
const pt: Point = .{
244+
// 在方法返回值中使用简写语法
245+
pub fn origin() Point {
246+
return .{ .x = 0, .y = 0 }; // 返回类型已声明为 Point,可推断
247+
}
248+
};
249+
250+
fn printPoint(p: Point) void {
251+
_ = p;
252+
}
253+
254+
pub fn main() void {
255+
// 完整语法:显式指定类型名称
256+
const pt1 = Point{ .x = 10, .y = 20 };
257+
258+
// 简写语法:当类型可推断时,可省略类型名称
259+
const pt2: Point = .{
223260
.x = 13,
224261
.y = 67,
225262
};
226-
// #endregion auto_reference
227263

228-
_ = pt;
264+
// 在方法返回值中使用简写
265+
const pt3 = Point.origin();
266+
267+
// 作为函数参数传递(参数类型已知时可推断)
268+
printPoint(.{ .x = 100, .y = 200 });
269+
270+
_ = pt1;
271+
_ = pt2;
272+
_ = pt3;
229273
}
274+
// #endregion struct_init_inferred
230275
};
231276

232277
// #region linked_list

0 commit comments

Comments
 (0)