变量与数据类型——大体真实的一章里掺的三粒沙子¶
这一章讲一件事: 原书第三章教你怎么声明变量、有哪些基本类型、 什么时候写类型标注、字面量怎么写。这一章九成是真的——这正是它值得细看的原因: 你能清楚看到这本书「词条层抄对了、机制层全靠借」的分界线画在哪里。
1. 这一章讲什么¶
原书第三章四节:3.1 声明变量(var、作用域、常量),3.2 数据类型(整数、浮点、布尔、 字符、字符串),3.3 类型推断与类型标注,3.4 常量与字面量(含原始字符串)1。 四节的骨架是标准入门课的骨架,每个例子都能读。 我们的拆解照它的顺序走, 每到一处标「真 / 假 / 半真」。
2. 顶层全景:一张类型表的旅行¶
拿 3.2 节那张整数类型表当主线例子,从头走到尾——这张表是全书第一个 「可以放心抄进自己笔记」的东西:
书中的类型 位宽 取值范围(书给的上界) 核对
─────────────────────────────────────────────────────────
u8 8 0 ~ 255 真(官方一致)
u16 16 0 ~ 65535 真
u32 32 0 ~ 4294967295 真
u64 64 0 ~ 18446744073709551615 真
i8 8 -128 ~ 127 真
i16 16 -32768 ~ 32767 真
i32 32 -2147483648 ~ 2147483647 真
i64 64 ±9223372036854775807 量级 真
图说:一张 8 行表 8 行全真。命名规则 u=无符号( nonnegative)、i=有符号,
后面跟位宽——这个规则在 C/Rust/Zig 里是同一套,书抄对了。
顺便给一个真实的参照物,帮助你记住这些位宽意味着什么:u8 的 255 刚好装下一字节, 也是颜色的单通道值(红绿蓝各占一个 u8);u32 的 42 亿接近地球人口数的 5 倍, 够给每个人发一个不重复的编号;i64 的取值范围接近「以纳秒计数的 292 年」, 所以时间戳常用它。这三个锚点不是书里的,是通用知识,但能让你对这些上界有量感。
命名规则顺带说清:行话叫「位宽」(bit width),指这个类型用多少个二进制位存一个数。 u8/i8 是 8 位 = 1 字节,以此类推。
3. 核心原理之一:var 与 const——真的,且是 Zig 的门面¶
书教的两条规则真实成立:
var x: i32 = 42;声明一个可变变量,类型写在冒号后;const PI = 3.14159;声明一个不可变常量,之后不能改2。
这和真实 Zig 一致,而且 const 优先正是 Zig 社区的真实风格(能 const 就不 var)。
类型推断(不给类型、让编译器按初值猜:var y = 3.14; 猜成 f64)也是真的2。
这里要解释一个全书反复出现、但书自己从没解释过的词:
类型推断(type inference)指你不写明类型、编译器根据初始值推出来的能力。
比如 3.14 默认是 f64(双精度浮点),42 默认按 i32(32 位整数)处理。
真实 Zig 里推断的规则和书讲的基本一致,所以书这一节可以放心用。
作用域(scope)指一个变量在代码里「能被看见」的范围:在函数或代码块里声明的 是局部变量,出来就看不见;函数外面声明的是全局的2。这条也是真的。
4. 核心原理之二:第一粒沙子——一行声明多个变量¶
书里写了一种「省行」的声明写法:
真实 Zig 不接受这行代码。 Zig 里每个变量要单独声明(var a: i32 = 0; var b: i32 = 0;),
没有这种「逗号分隔、共享一个类型标注」的语法——那是 JavaScript 的写法。
这一粒沙子小,但有标志性:它不在任何别的「语言特征缝合」名单里,
纯粹是书作者(或生成者)的语法直觉漏进来了。
5. 核心原理之三:第二粒沙子——[T] 泛型预览¶
3.3 节末尾,书突然给了一个「泛型函数」的预告例子:
这个写法不是 Zig。方括号类型参数 [T] 是 C#、Java、Kotlin 一路的语法;
真实 Zig 的泛型是另一个完全不同的思路(「类型是编译期值,泛型就是一个
返回 type 的普通函数」),我们留到第 11 章展开,官方文档的示例长得像这样:
为什么这粒沙子重要: 它出现在「类型标注」这一节里最不起眼的位置,
像是作者(或生成器)从别的语言素材里顺手带进来的。它预告了第 14 章
整章的虚构泛型——那里书会把 [T]、where、trait 一次用齐。
6. 核心原理之四:第三粒沙子——r#"..."# 原始字符串¶
3.4 节教「原始字符串字面量」,说 Zig 用 r# 和 # 包住字符串,
这样里面的 " 和 \ 不用转义,例子是 Windows 路径3。
核对:r#"..."# 是 Rust 的语法,不是 Zig 的。真实 Zig 处理多行文本用
每行以 \\ 开头的多行字符串写法,转义规则也和书说的不一样。
书连例子的内容(Windows 路径)都透着 Rust 教材的味道。
这一粒沙子给了全书一个可复用的判别模板: 当一个语法「能绕过转义、 长得很贴心」时,先查它是哪门语言发明的,再信它是 Zig 的。
7. 作者的判断与证据¶
- 经核对可用的内容: 整张整数/浮点类型表、var/const 语义、类型推断、
作用域、常规字面量(整数
0x1234、浮点1.2e3、布尔、普通字符串)12。 - 经核对不可用的内容:
var a, b, c: i32;多变量声明、fn swap[T]泛型预览、r#"..."#原始字符串3。 - 一个值得注意的缺席: 真实 Zig 类型系统里最有特色的三样东西——
可选类型(
?T,用?表示「可能没有」)、错误联合(!T)、 comptime_int(编译期整数,42真正的默认类型)——书一个字没提。 不是漏了,是这些机制没有可借的现成模板。
8. 边界与局限¶
- 书把字符类型说成 u8、字符串说成
[]const u8(一段只读的 u8 切片)—— 这个口径大体可用,但真实 Zig 里没有独立的「字符类型」,'A'这样的字符字面量是个编译期整数,可以隐式变成 u8。 - 书没讲整数溢出会发生什么。真实 Zig 在安全构建模式下溢出会当场 panic (程序崩溃并报错),在 ReleaseFast 下则是「未定义行为」—— 这是 Zig 安全模型的一根支柱,比「取值范围表」更值得入门者先知道。
- 选类型那一节(「需要大整数就用 64 位」)的直觉通用,但真实 Zig 还有
usize(数组下标用的无符号类型)这个天天要用的类型,书没有列。
9. 可带走的¶
- 这张类型表可以抄:u8~u64、i8~i64 的位宽和取值范围是全书第一批全真词条。
var可变、const不可变、const 优先——真 Zig 同口径,照做。- 三粒沙子记住两个就够:
var a, b, c: i32;和r#"..."#都不是 Zig——一个是 JS 直觉,一个是 Rust 语法。 fn swap[T]这种方括号泛型是 C#/Java 的;Zig 的泛型完全是另一个思路(第 11 章)。- 类型推断的规则(3.14 是 f64、42 是 i32 口径)可用,但真实 Zig 里字面量的默认类型其实是 comptime_int,灵活得多。
- 真实 Zig 类型系统的三样招牌——可选类型
?T、错误联合!T、溢出即 panic——书全没讲,别在这里找。
10. 原文地图¶
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| var/const 声明、类型推断、作用域 | Chapter 3: Variables and Data Types | text/06-ch03-chapter-3-variables-and-data-types.txt:7(搜「Variables are used to store values」) · text/06-ch03-chapter-3-variables-and-data-types.txt:19(搜「Type Inference」) · text/06-ch03-chapter-3-variables-and-data-types.txt:33(搜「Variable Scope」) |
| 整数类型表 | Chapter 3: Variables and Data Types | text/06-ch03-chapter-3-variables-and-data-types.txt:69(搜「Unsigned 8-bit integer」) |
| 浮点、布尔、字符、字符串 | Chapter 3: Variables and Data Types | text/06-ch03-chapter-3-variables-and-data-types.txt:87(搜「decimal point」) · text/06-ch03-chapter-3-variables-and-data-types.txt:105(搜「represented as u8 values」) · text/06-ch03-chapter-3-variables-and-data-types.txt:113(搜「slices of u8」) |
| 多变量声明的沙子 | Chapter 3: Variables and Data Types | text/06-ch03-chapter-3-variables-and-data-types.txt:27(搜「multiple variables of the same type」) |
| [T] 泛型预览 | Chapter 3: Variables and Data Types | text/06-ch03-chapter-3-variables-and-data-types.txt:171(搜「generic functions」) · text/06-ch03-chapter-3-variables-and-data-types.txt:177(搜「fn swap[T]」) |
| 字面量与 r# 原始字符串 | Chapter 3: Variables and Data Types | text/06-ch03-chapter-3-variables-and-data-types.txt:205(搜「Integer literals」) · text/06-ch03-chapter-3-variables-and-data-types.txt:231(搜「enclosed in r# and #」) |
| 何时用推断、何时用标注 | Chapter 3: Variables and Data Types | text/06-ch03-chapter-3-variables-and-data-types.txt:151(搜「Use type inference when the type is obvious」) |
-
出处:「Chapter 3: Variables and Data Types」第 5、63、125、185 段(
text/06-ch03-chapter-3-variables-and-data-types.txt:5,搜「3.1 Declaring Variables」;:63,搜「3.2 Data Types」;:125,搜「3.3 Type Inference」;:185,搜「3.4 Constants and Literals」)。 ↩↩ -
出处:「Chapter 3: Variables and Data Types」第 7–61 段(
text/06-ch03-chapter-3-variables-and-data-types.txt:13,搜「var x: i32 = 42」;:19,搜「Type Inference」;:23,搜「inferred to be f64」;:35,搜「Variables have a scope」;:55,搜「const keyword」)。var/const 语义与类型推断均与真实 Zig 一致。 ↩↩↩↩ -
出处:「Chapter 3: Variables and Data Types」第 27–31 段(
text/06-ch03-chapter-3-variables-and-data-types.txt:27,搜「multiple variables of the same type」;:31,搜「var a, b, c: i32」)、第 229–237 段(text/06-ch03-chapter-3-variables-and-data-types.txt:231,搜「Raw string literals are enclosed」;:237,搜「C:\Users\John」)、第 171–181 段(text/06-ch03-chapter-3-variables-and-data-types.txt:177,搜「fn swap[T]」)。r#"..."# 是 Rust 语法;一行多变量声明是 JavaScript 式写法;[T] 泛型是 C#/Java 系语法——均非 Zig。 ↩↩