-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathch05-01-defining-structs.html
164 lines (159 loc) · 54.8 KB
/
ch05-01-defining-structs.html
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>定义并实例化结构体</title>
<meta name="generator" content="VuePress 1.5.3">
<meta name="description" content="">
<link rel="preload" href="/assets/css/0.styles.12e35fbb.css" as="style"><link rel="preload" href="/assets/js/app.e6b14c5e.js" as="script"><link rel="preload" href="/assets/js/3.ecc21787.js" as="script"><link rel="preload" href="/assets/js/1.032ec45e.js" as="script"><link rel="preload" href="/assets/js/38.9aaa7af9.js" as="script"><link rel="prefetch" href="/assets/js/10.0db432dd.js"><link rel="prefetch" href="/assets/js/100.1149107d.js"><link rel="prefetch" href="/assets/js/101.feae8ac2.js"><link rel="prefetch" href="/assets/js/102.4be35ad2.js"><link rel="prefetch" href="/assets/js/103.cb0bcc26.js"><link rel="prefetch" href="/assets/js/104.581a9df8.js"><link rel="prefetch" href="/assets/js/105.a5b31ce3.js"><link rel="prefetch" href="/assets/js/106.feb2cd4c.js"><link rel="prefetch" href="/assets/js/107.c74c3f7d.js"><link rel="prefetch" href="/assets/js/108.6a32c62d.js"><link rel="prefetch" href="/assets/js/109.3c3188fd.js"><link rel="prefetch" href="/assets/js/11.04463d2c.js"><link rel="prefetch" href="/assets/js/110.5f3f2327.js"><link rel="prefetch" href="/assets/js/111.374cf29b.js"><link rel="prefetch" href="/assets/js/112.37a66948.js"><link rel="prefetch" href="/assets/js/113.0e87d41d.js"><link rel="prefetch" href="/assets/js/114.e2641184.js"><link rel="prefetch" href="/assets/js/115.903cb5c3.js"><link rel="prefetch" href="/assets/js/116.d1cfad4c.js"><link rel="prefetch" href="/assets/js/117.ca412492.js"><link rel="prefetch" href="/assets/js/118.23919bb0.js"><link rel="prefetch" href="/assets/js/12.2de3af2e.js"><link rel="prefetch" href="/assets/js/13.69a23a33.js"><link rel="prefetch" href="/assets/js/14.3335c861.js"><link rel="prefetch" href="/assets/js/15.a469e71d.js"><link rel="prefetch" href="/assets/js/16.ee173d9e.js"><link rel="prefetch" href="/assets/js/17.959da5cf.js"><link rel="prefetch" href="/assets/js/18.0aa8fea6.js"><link rel="prefetch" href="/assets/js/19.21e6464d.js"><link rel="prefetch" href="/assets/js/20.b6d578fe.js"><link rel="prefetch" href="/assets/js/21.986be82f.js"><link rel="prefetch" href="/assets/js/22.47be6a63.js"><link rel="prefetch" href="/assets/js/23.15fe85eb.js"><link rel="prefetch" href="/assets/js/24.b3a04842.js"><link rel="prefetch" href="/assets/js/25.ae75ed87.js"><link rel="prefetch" href="/assets/js/26.643de6d4.js"><link rel="prefetch" href="/assets/js/27.6663d0a9.js"><link rel="prefetch" href="/assets/js/28.4669e096.js"><link rel="prefetch" href="/assets/js/29.65085b51.js"><link rel="prefetch" href="/assets/js/30.b4315895.js"><link rel="prefetch" href="/assets/js/31.e7ecf0dd.js"><link rel="prefetch" href="/assets/js/32.5d1db543.js"><link rel="prefetch" href="/assets/js/33.e8747222.js"><link rel="prefetch" href="/assets/js/34.852658b5.js"><link rel="prefetch" href="/assets/js/35.fa3f0352.js"><link rel="prefetch" href="/assets/js/36.8ebb5fa0.js"><link rel="prefetch" href="/assets/js/37.fa05856b.js"><link rel="prefetch" href="/assets/js/39.1a8b291e.js"><link rel="prefetch" href="/assets/js/4.f09c27b1.js"><link rel="prefetch" href="/assets/js/40.b9a756f6.js"><link rel="prefetch" href="/assets/js/41.7cef9fb3.js"><link rel="prefetch" href="/assets/js/42.04a2dfd5.js"><link rel="prefetch" href="/assets/js/43.b586e125.js"><link rel="prefetch" href="/assets/js/44.83db3147.js"><link rel="prefetch" href="/assets/js/45.e09151dc.js"><link rel="prefetch" href="/assets/js/46.f4d7d1f9.js"><link rel="prefetch" href="/assets/js/47.b935a8bb.js"><link rel="prefetch" href="/assets/js/48.10681e24.js"><link rel="prefetch" href="/assets/js/49.04036517.js"><link rel="prefetch" href="/assets/js/5.9229c7e7.js"><link rel="prefetch" href="/assets/js/50.385b0179.js"><link rel="prefetch" href="/assets/js/51.0a5c574d.js"><link rel="prefetch" href="/assets/js/52.5cd11b21.js"><link rel="prefetch" href="/assets/js/53.2efb9eb9.js"><link rel="prefetch" href="/assets/js/54.dd3a8f7d.js"><link rel="prefetch" href="/assets/js/55.e72498d3.js"><link rel="prefetch" href="/assets/js/56.5611b803.js"><link rel="prefetch" href="/assets/js/57.004dcc8a.js"><link rel="prefetch" href="/assets/js/58.de3a101d.js"><link rel="prefetch" href="/assets/js/59.a4d35b66.js"><link rel="prefetch" href="/assets/js/6.2ede05ad.js"><link rel="prefetch" href="/assets/js/60.ffa87f2b.js"><link rel="prefetch" href="/assets/js/61.c97c2157.js"><link rel="prefetch" href="/assets/js/62.1a964fd5.js"><link rel="prefetch" href="/assets/js/63.4fadefff.js"><link rel="prefetch" href="/assets/js/64.b0507c62.js"><link rel="prefetch" href="/assets/js/65.09fcdb27.js"><link rel="prefetch" href="/assets/js/66.c8f8a5cc.js"><link rel="prefetch" href="/assets/js/67.02fa33de.js"><link rel="prefetch" href="/assets/js/68.d49f848f.js"><link rel="prefetch" href="/assets/js/69.9dc909c1.js"><link rel="prefetch" href="/assets/js/7.00d72aac.js"><link rel="prefetch" href="/assets/js/70.e9702890.js"><link rel="prefetch" href="/assets/js/71.41a43a69.js"><link rel="prefetch" href="/assets/js/72.9f6f3145.js"><link rel="prefetch" href="/assets/js/73.64d032a1.js"><link rel="prefetch" href="/assets/js/74.6bb7d811.js"><link rel="prefetch" href="/assets/js/75.f9ddba21.js"><link rel="prefetch" href="/assets/js/76.ad390b83.js"><link rel="prefetch" href="/assets/js/77.bc150afb.js"><link rel="prefetch" href="/assets/js/78.69dc1271.js"><link rel="prefetch" href="/assets/js/79.5ce4cf53.js"><link rel="prefetch" href="/assets/js/8.f3a923c0.js"><link rel="prefetch" href="/assets/js/80.a9598d24.js"><link rel="prefetch" href="/assets/js/81.b1ca9b22.js"><link rel="prefetch" href="/assets/js/82.1017a114.js"><link rel="prefetch" href="/assets/js/83.d4fdce6e.js"><link rel="prefetch" href="/assets/js/84.f13715fe.js"><link rel="prefetch" href="/assets/js/85.af5497b5.js"><link rel="prefetch" href="/assets/js/86.07fb3684.js"><link rel="prefetch" href="/assets/js/87.d175c777.js"><link rel="prefetch" href="/assets/js/88.aa6d98dd.js"><link rel="prefetch" href="/assets/js/89.3d1bef74.js"><link rel="prefetch" href="/assets/js/9.3c7c9ecc.js"><link rel="prefetch" href="/assets/js/90.f46d49e9.js"><link rel="prefetch" href="/assets/js/91.6f0b514b.js"><link rel="prefetch" href="/assets/js/92.5a1abbdf.js"><link rel="prefetch" href="/assets/js/93.c50314c2.js"><link rel="prefetch" href="/assets/js/94.becb0d94.js"><link rel="prefetch" href="/assets/js/95.cc5ea7c4.js"><link rel="prefetch" href="/assets/js/96.1ba1f23b.js"><link rel="prefetch" href="/assets/js/97.0436550a.js"><link rel="prefetch" href="/assets/js/98.180142a4.js"><link rel="prefetch" href="/assets/js/99.fa82e156.js">
<link rel="stylesheet" href="/assets/css/0.styles.12e35fbb.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container" data-v-dad8a512><div data-v-dad8a512><div id="loader-wrapper" class="loading-wrapper" data-v-d48f4d20 data-v-dad8a512 data-v-dad8a512><div class="loader-main" data-v-d48f4d20><div data-v-d48f4d20></div><div data-v-d48f4d20></div><div data-v-d48f4d20></div><div data-v-d48f4d20></div></div> <!----> <!----></div> <div class="password-shadow password-wrapper-out" style="display:none;" data-v-64685f0e data-v-dad8a512 data-v-dad8a512><h3 class="title" style="display:none;" data-v-64685f0e data-v-64685f0e></h3> <!----> <label id="box" class="inputBox" style="display:none;" data-v-64685f0e data-v-64685f0e><input type="password" value="" data-v-64685f0e> <span data-v-64685f0e>Konck! Knock!</span> <button data-v-64685f0e>OK</button></label> <div class="footer" style="display:none;" data-v-64685f0e data-v-64685f0e><span data-v-64685f0e><i class="iconfont reco-theme" data-v-64685f0e></i> <a target="blank" href="https://vuepress-theme-reco.recoluan.com" data-v-64685f0e>vuePress-theme-reco</a></span> <span data-v-64685f0e><i class="iconfont reco-copyright" data-v-64685f0e></i> <a data-v-64685f0e><!---->
<!---->
2020
</a></span></div></div> <div class="hide" data-v-dad8a512><header class="navbar" data-v-dad8a512><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"></a> <div class="links"><div class="color-picker"><a class="color-button"><i class="iconfont reco-color"></i></a> <div class="color-picker-menu" style="display:none;"><div class="mode-options"><h4 class="title">Choose mode</h4> <ul class="color-mode-options"><li class="dark">dark</li><li class="auto active">auto</li><li class="light">light</li></ul></div></div></div> <div class="search-box"><i class="iconfont reco-search"></i> <input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/" class="nav-link"><i class="iconfont undefined"></i>
回首页
</a></div> <!----></nav></div></header> <div class="sidebar-mask" data-v-dad8a512></div> <aside class="sidebar" data-v-dad8a512><div class="personal-info-wrapper" data-v-ca798c94 data-v-dad8a512><!----> <!----> <div class="num" data-v-ca798c94><div data-v-ca798c94><h3 data-v-ca798c94>0</h3> <h6 data-v-ca798c94>Article</h6></div> <div data-v-ca798c94><h3 data-v-ca798c94>0</h3> <h6 data-v-ca798c94>Tag</h6></div></div> <hr data-v-ca798c94></div> <nav class="nav-links"><div class="nav-item"><a href="/" class="nav-link"><i class="iconfont undefined"></i>
回首页
</a></div> <!----></nav> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><a href="/title-page" class="sidebar-heading clickable open"><span>Rust 程序设计语言</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/foreword.html" class="sidebar-link">前言</a></li><li><a href="/ch00-00-introduction.html" class="sidebar-link">介绍</a></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch01-00-getting-started.html" class="sidebar-heading clickable"><span>1. 入门指南</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch01-01-installation.html" class="sidebar-link">1.1. 安装</a></li><li><a href="/ch01-02-hello-world.html" class="sidebar-link">1.2. Hello, World!</a></li><li><a href="/ch01-03-hello-cargo.html" class="sidebar-link">1.3. Hello, Cargo!</a></li></ul></section></li><li><a href="/ch02-00-guessing-game-tutorial.html" class="sidebar-link">2. 猜猜看游戏教程</a></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch03-00-common-programming-concepts.html" class="sidebar-heading clickable"><span>3. 常见编程概念</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch03-01-variables-and-mutability.html" class="sidebar-link">3.1. 变量与可变性</a></li><li><a href="/ch03-02-data-types.html" class="sidebar-link">3.2. 数据类型</a></li><li><a href="/ch03-03-how-functions-work.html" class="sidebar-link">3.3. 函数如何工作</a></li><li><a href="/ch03-04-comments.html" class="sidebar-link">3.4. 注释</a></li><li><a href="/ch03-05-control-flow.html" class="sidebar-link">3.5. 控制流</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch04-00-understanding-ownership.html" class="sidebar-heading clickable"><span>4. 认识所有权</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch04-01-what-is-ownership.html" class="sidebar-link">4.1. 什么是所有权?</a></li><li><a href="/ch04-02-references-and-borrowing.html" class="sidebar-link">4.2. 引用与借用</a></li><li><a href="/ch04-03-slices.html" class="sidebar-link">4.3. Slices</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch05-00-structs.html" class="sidebar-heading clickable open"><span>5. 使用结构体来组织相关联的数据</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch05-01-defining-structs.html" aria-current="page" class="active sidebar-link">5.1. 定义并实例化结构体</a></li><li><a href="/ch05-02-example-structs.html" class="sidebar-link">5.2. 一个使用结构体的示例程序</a></li><li><a href="/ch05-03-method-syntax.html" class="sidebar-link">5.3. 方法语法</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch06-00-enums.html" class="sidebar-heading clickable"><span>6. 枚举与模式匹配</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch06-01-defining-an-enum.html" class="sidebar-link">6.1. 定义枚举</a></li><li><a href="/ch06-02-match.html" class="sidebar-link">6.2. match控制流运算符</a></li><li><a href="/ch06-03-if-let.html" class="sidebar-link">6.3. if let简洁控制流</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch07-00-managing-growing-projects-with-packages-crates-and-modules.html" class="sidebar-heading clickable"><span>7. 使用包、Crate 和模块管理不断增长的项目</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch07-01-packages-and-crates.html" class="sidebar-link">7.1. 包和 crate</a></li><li><a href="/ch07-02-defining-modules-to-control-scope-and-privacy.html" class="sidebar-link">7.2. 定义模块来控制作用域与私有性</a></li><li><a href="/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html" class="sidebar-link">7.3. 路径用于引用模块树中的项</a></li><li><a href="/ch07-04-bringing-paths-into-scope-with-the-use-keyword.html" class="sidebar-link">7.4. 使用use关键字将名称引入作用域</a></li><li><a href="/ch07-05-separating-modules-into-different-files.html" class="sidebar-link">7.5. 将模块分割进不同文件</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch08-00-common-collections.html" class="sidebar-heading clickable"><span>8. 常见集合</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch08-01-vectors.html" class="sidebar-link">8.1. vector</a></li><li><a href="/ch08-02-strings.html" class="sidebar-link">8.2. 字符串</a></li><li><a href="/ch08-03-hash-maps.html" class="sidebar-link">8.3. 哈希 map</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch09-00-error-handling.html" class="sidebar-heading clickable"><span>9. 错误处理</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch09-01-unrecoverable-errors-with-panic.html" class="sidebar-link">9.1. panic!与不可恢复的错误</a></li><li><a href="/ch09-02-recoverable-errors-with-result.html" class="sidebar-link">9.2. Result与可恢复的错误</a></li><li><a href="/ch09-03-to-panic-or-not-to-panic.html" class="sidebar-link">9.3. panic!还是不panic!</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch10-00-generics.html" class="sidebar-heading clickable"><span>10. 泛型、trait 与生命周期</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch10-01-syntax.html" class="sidebar-link">10.1. 泛型数据类型</a></li><li><a href="/ch10-02-traits.html" class="sidebar-link">10.2. trait:定义共享的行为</a></li><li><a href="/ch10-03-lifetime-syntax.html" class="sidebar-link">10.3. 生命周期与引用有效性</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch11-00-testing.html" class="sidebar-heading clickable"><span>11. 测试</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch11-01-writing-tests.html" class="sidebar-link">11.1. 编写测试</a></li><li><a href="/ch11-02-running-tests.html" class="sidebar-link">11.2. 运行测试</a></li><li><a href="/ch11-03-test-organization.html" class="sidebar-link">11.3. 测试的组织结构</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch12-00-an-io-project.html" class="sidebar-heading clickable"><span>12. 一个 I/O 项目:构建命令行程序</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch12-01-accepting-command-line-arguments.html" class="sidebar-link">12.1. 接受命令行参数</a></li><li><a href="/ch12-02-reading-a-file.html" class="sidebar-link">12.2. 读取文件</a></li><li><a href="/ch12-03-improving-error-handling-and-modularity.html" class="sidebar-link">12.3. 重构以改进模块化与错误处理</a></li><li><a href="/ch12-04-testing-the-librarys-functionality.html" class="sidebar-link">12.4. 采用测试驱动开发完善库的功能</a></li><li><a href="/ch12-05-working-with-environment-variables.html" class="sidebar-link">12.5. 处理环境变量</a></li><li><a href="/ch12-06-writing-to-stderr-instead-of-stdout.html" class="sidebar-link">12.6. 将错误信息输出到标准错误而不是标准输出</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch13-00-functional-features.html" class="sidebar-heading clickable"><span>13. Rust 中的函数式语言功能:迭代器与闭包</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch13-01-closures.html" class="sidebar-link">13.1. 闭包:可以捕获其环境的匿名函数</a></li><li><a href="/ch13-02-iterators.html" class="sidebar-link">13.2. 使用迭代器处理元素序列</a></li><li><a href="/ch13-03-improving-our-io-project.html" class="sidebar-link">13.3. 改进之前的 I/O 项目</a></li><li><a href="/ch13-04-performance.html" class="sidebar-link">13.4. 性能比较:循环对迭代器</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch14-00-more-about-cargo.html" class="sidebar-heading clickable"><span>14. 更多关于 Cargo 和 Crates.io 的内容</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch14-01-release-profiles.html" class="sidebar-link">14.1. 采用发布配置自定义构建</a></li><li><a href="/ch14-02-publishing-to-crates-io.html" class="sidebar-link">14.2. 将 crate 发布到 Crates.io</a></li><li><a href="/ch14-03-cargo-workspaces.html" class="sidebar-link">14.3. Cargo 工作空间</a></li><li><a href="/ch14-04-installing-binaries.html" class="sidebar-link">14.4. 使用cargo install从 Crates.io 安装二进制文件</a></li><li><a href="/ch14-05-extending-cargo.html" class="sidebar-link">14.5. Cargo 自定义扩展命令</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch15-00-smart-pointers.html" class="sidebar-heading clickable"><span>15. 智能指针</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch15-01-box.html" class="sidebar-link">15.1. Box<T>指向堆上数据,并且可确定大小</a></li><li><a href="/ch15-02-deref.html" class="sidebar-link">15.2. 通过Dereftrait 将智能指针当作常规引用处理</a></li><li><a href="/ch15-03-drop.html" class="sidebar-link">15.3. DropTrait 运行清理代码</a></li><li><a href="/ch15-04-rc.html" class="sidebar-link">15.4. Rc<T>引用计数智能指针</a></li><li><a href="/ch15-05-interior-mutability.html" class="sidebar-link">15.5. RefCell<T>与内部可变性模式</a></li><li><a href="/ch15-06-reference-cycles.html" class="sidebar-link">15.6. 引用循环与内存泄漏是安全的</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch16-00-concurrency.html" class="sidebar-heading clickable"><span>16. 无畏并发</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch16-01-threads.html" class="sidebar-link">16.1. 线程</a></li><li><a href="/ch16-02-message-passing.html" class="sidebar-link">16.2. 消息传递</a></li><li><a href="/ch16-03-shared-state.html" class="sidebar-link">16.3. 共享状态</a></li><li><a href="/ch16-04-extensible-concurrency-sync-and-send.html" class="sidebar-link">16.4. 可扩展的并发:Sync与Send</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch17-00-oop.html" class="sidebar-heading clickable"><span>17. Rust 的面向对象编程特性</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch17-01-what-is-oo.html" class="sidebar-link">17.1. 面向对象语言的特点</a></li><li><a href="/ch17-02-trait-objects.html" class="sidebar-link">17.2. 为使用不同类型的值而设计的 trait 对象</a></li><li><a href="/ch17-03-oo-design-patterns.html" class="sidebar-link">17.3. 面向对象设计模式的实现</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch18-00-patterns.html" class="sidebar-heading clickable"><span>18. 模式用来匹配值的结构</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch18-01-all-the-places-for-patterns.html" class="sidebar-link">18.1. 所有可能会用到模式的位置</a></li><li><a href="/ch18-02-refutability.html" class="sidebar-link">18.2. Refutability:何时模式可能会匹配失败</a></li><li><a href="/ch18-03-pattern-syntax.html" class="sidebar-link">18.3. 模式的全部语法</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch19-00-advanced-features.html" class="sidebar-heading clickable"><span>19. 高级特征</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch19-01-unsafe-rust.html" class="sidebar-link">19.1. 不安全的 Rust</a></li><li><a href="/ch19-03-advanced-traits.html" class="sidebar-link">19.2. 高级 trait</a></li><li><a href="/ch19-04-advanced-types.html" class="sidebar-link">19.3. 高级类型</a></li><li><a href="/ch19-05-advanced-functions-and-closures.html" class="sidebar-link">19.4. 高级函数与闭包</a></li><li><a href="/ch19-06-macros.html" class="sidebar-link">19.5. 宏</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/ch20-00-final-project-a-web-server.html" class="sidebar-heading clickable"><span>20. 最后的项目: 构建多线程 web server</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/ch20-01-single-threaded.html" class="sidebar-link">20.1. 单线程 web server</a></li><li><a href="/ch20-02-multithreaded.html" class="sidebar-link">20.2. 将单线程 server 变为多线程 server</a></li><li><a href="/ch20-03-graceful-shutdown-and-cleanup.html" class="sidebar-link">20.3. 优雅停机与清理</a></li></ul></section></li><li><section class="sidebar-group is-sub-group depth-1"><a href="/appendix-00.html" class="sidebar-heading clickable"><span>21. 附录</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/appendix-01-keywords.html" class="sidebar-link">21.1. A - 关键字</a></li><li><a href="/appendix-02-operators.html" class="sidebar-link">21.2. B - 运算符与符号</a></li><li><a href="/appendix-03-derivable-traits.html" class="sidebar-link">21.3. C - 可派生的 trait</a></li><li><a href="/appendix-04-useful-development-tools.html" class="sidebar-link">21.4. D - 实用开发工具</a></li><li><a href="/appendix-05-editions.html" class="sidebar-link">21.5. E - 版本</a></li><li><a href="/appendix-06-translation.html" class="sidebar-link">21.6. F - 本书译本</a></li><li><a href="/appendix-07-nightly-rust.html" class="sidebar-link">21.7. G - Rust 是如何开发的与 “Nightly Rust”</a></li></ul></section></li></ul></section></li></ul> </aside> <div class="password-shadow password-wrapper-in" style="display:none;" data-v-64685f0e data-v-dad8a512><h3 class="title" style="display:none;" data-v-64685f0e data-v-64685f0e></h3> <!----> <label id="box" class="inputBox" style="display:none;" data-v-64685f0e data-v-64685f0e><input type="password" value="" data-v-64685f0e> <span data-v-64685f0e>Konck! Knock!</span> <button data-v-64685f0e>OK</button></label> <div class="footer" style="display:none;" data-v-64685f0e data-v-64685f0e><span data-v-64685f0e><i class="iconfont reco-theme" data-v-64685f0e></i> <a target="blank" href="https://vuepress-theme-reco.recoluan.com" data-v-64685f0e>vuePress-theme-reco</a></span> <span data-v-64685f0e><i class="iconfont reco-copyright" data-v-64685f0e></i> <a data-v-64685f0e><!---->
<!---->
2020
</a></span></div></div> <div data-v-dad8a512><main class="page"><div class="page-title" style="display:none;"><h1>定义并实例化结构体</h1> <div data-v-3b7f5bdf><!----> <!----> <!----> <!----></div></div> <div class="theme-reco-content content__default" style="display:none;"><h2 id="定义并实例化结构体"><a href="#定义并实例化结构体" class="header-anchor">#</a> 定义并实例化结构体</h2> <blockquote><p><a href="https://github.com/rust-lang/book/blob/master/src/ch05-01-defining-structs.md" target="_blank" rel="noopener noreferrer">ch05-01-defining-structs.md<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> <br>
commit f617d58c1a88dd2912739a041fd4725d127bf9fb</p></blockquote> <p>结构体和我们在第三章讨论过的元组类似。和元组一样,结构体的每一部分可以是不同类型。但不同于元组,结构体需要命名各部分数据以便能清楚的表明其值的意义。由于有了这些名字,结构体比元组更灵活:不需要依赖顺序来指定或访问实例中的值。</p> <p>定义结构体,需要使用 <code>struct</code> 关键字并为整个结构体提供一个名字。结构体的名字需要描述它所组合的数据的意义。接着,在大括号中,定义每一部分数据的名字和类型,我们称为 <strong>字段</strong>(<em>field</em>)。例如,示例 5-1 展示了一个存储用户账号信息的结构体:</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">struct</span> <span class="token type-definition class-name">User</span> <span class="token punctuation">{</span>
username<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span>
email<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span>
sign_in_count<span class="token punctuation">:</span> <span class="token keyword">u64</span><span class="token punctuation">,</span>
active<span class="token punctuation">:</span> <span class="token keyword">bool</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><p><span class="caption">示例 5-1:<code>User</code> 结构体定义</span></p> <p>一旦定义了结构体后,为了使用它,通过为每个字段指定具体值来创建这个结构体的 <strong>实例</strong>。创建一个实例需要以结构体的名字开头,接着在大括号中使用 <code>key: value</code> 键-值对的形式提供字段,其中 key 是字段的名字,value 是需要存储在字段中的数据值。实例中字段的顺序不需要和它们在结构体中声明的顺序一致。换句话说,结构体的定义就像一个类型的通用模板,而实例则会在这个模板中放入特定数据来创建这个类型的值。例如,可以像示例 5-2 这样来声明一个特定的用户:</p> <div class="language-rust extra-class"><pre class="language-rust"><code># <span class="token keyword">struct</span> <span class="token type-definition class-name">User</span> <span class="token punctuation">{</span>
# username<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span>
# email<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span>
# sign_in_count<span class="token punctuation">:</span> <span class="token keyword">u64</span><span class="token punctuation">,</span>
# active<span class="token punctuation">:</span> <span class="token keyword">bool</span><span class="token punctuation">,</span>
# <span class="token punctuation">}</span>
#
<span class="token keyword">let</span> user1 <span class="token operator">=</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
email<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"[email protected]"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
username<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"someusername123"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
active<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
sign_in_count<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p><span class="caption">示例 5-2:创建 <code>User</code> 结构体的实例</span></p> <p>为了从结构体中获取某个特定的值,可以使用点号。如果我们只想要用户的邮箱地址,可以用 <code>user1.email</code>。要更改结构体中的值,如果结构体的实例是可变的,我们可以使用点号并为对应的字段赋值。示例 5-3 展示了如何改变一个可变的 <code>User</code> 实例 <code>email</code> 字段的值:</p> <div class="language-rust extra-class"><pre class="language-rust"><code># <span class="token keyword">struct</span> <span class="token type-definition class-name">User</span> <span class="token punctuation">{</span>
# username<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span>
# email<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span>
# sign_in_count<span class="token punctuation">:</span> <span class="token keyword">u64</span><span class="token punctuation">,</span>
# active<span class="token punctuation">:</span> <span class="token keyword">bool</span><span class="token punctuation">,</span>
# <span class="token punctuation">}</span>
#
<span class="token keyword">let</span> <span class="token keyword">mut</span> user1 <span class="token operator">=</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
email<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"[email protected]"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
username<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"someusername123"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
active<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
sign_in_count<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
user1<span class="token punctuation">.</span>email <span class="token operator">=</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"[email protected]"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p><span class="caption">示例 5-3:改变 <code>User</code> 实例 <code>email</code> 字段的值</span></p> <p>注意整个实例必须是可变的;Rust 并不允许只将某个字段标记为可变。另外需要注意同其他任何表达式一样,我们可以在函数体的最后一个表达式中构造一个结构体的新实例,来隐式地返回这个实例。</p> <p>示例 5-4 显示了一个 <code>build_user</code> 函数,它返回一个带有给定的 email 和用户名的 <code>User</code> 结构体实例。<code>active</code> 字段的值为 <code>true</code>,并且 <code>sign_in_count</code> 的值为 <code>1</code>。</p> <div class="language-rust extra-class"><pre class="language-rust"><code># <span class="token keyword">struct</span> <span class="token type-definition class-name">User</span> <span class="token punctuation">{</span>
# username<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span>
# email<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span>
# sign_in_count<span class="token punctuation">:</span> <span class="token keyword">u64</span><span class="token punctuation">,</span>
# active<span class="token punctuation">:</span> <span class="token keyword">bool</span><span class="token punctuation">,</span>
# <span class="token punctuation">}</span>
#
<span class="token keyword">fn</span> <span class="token function-definition function">build_user</span><span class="token punctuation">(</span>email<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span> username<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
<span class="token class-name">User</span> <span class="token punctuation">{</span>
email<span class="token punctuation">:</span> email<span class="token punctuation">,</span>
username<span class="token punctuation">:</span> username<span class="token punctuation">,</span>
active<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
sign_in_count<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p><span class="caption">示例 5-4:<code>build_user</code> 函数获取 email 和用户名并返回 <code>User</code> 实例</span></p> <p>为函数参数起与结构体字段相同的名字是可以理解的,但是不得不重复 <code>email</code> 和 <code>username</code> 字段名称与变量有些啰嗦。如果结构体有更多字段,重复每个名称就更加烦人了。幸运的是,有一个方便的简写语法!</p> <h3 id="变量与字段同名时的字段初始化简写语法"><a href="#变量与字段同名时的字段初始化简写语法" class="header-anchor">#</a> 变量与字段同名时的字段初始化简写语法</h3> <p>因为示例 5-4 中的参数名与字段名都完全相同,我们可以使用 <strong>字段初始化简写语法</strong>(<em>field init shorthand</em>)来重写 <code>build_user</code>,这样其行为与之前完全相同,不过无需重复 <code>email</code> 和 <code>username</code> 了,如示例 5-5 所示。</p> <div class="language-rust extra-class"><pre class="language-rust"><code># <span class="token keyword">struct</span> <span class="token type-definition class-name">User</span> <span class="token punctuation">{</span>
# username<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span>
# email<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span>
# sign_in_count<span class="token punctuation">:</span> <span class="token keyword">u64</span><span class="token punctuation">,</span>
# active<span class="token punctuation">:</span> <span class="token keyword">bool</span><span class="token punctuation">,</span>
# <span class="token punctuation">}</span>
#
<span class="token keyword">fn</span> <span class="token function-definition function">build_user</span><span class="token punctuation">(</span>email<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span> username<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
<span class="token class-name">User</span> <span class="token punctuation">{</span>
email<span class="token punctuation">,</span>
username<span class="token punctuation">,</span>
active<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
sign_in_count<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p><span class="caption">示例 5-5:<code>build_user</code> 函数使用了字段初始化简写语法,因为 <code>email</code> 和 <code>username</code> 参数与结构体字段同名</span></p> <p>这里我们创建了一个新的 <code>User</code> 结构体实例,它有一个叫做 <code>email</code> 的字段。我们想要将 <code>email</code> 字段的值设置为 <code>build_user</code> 函数 <code>email</code> 参数的值。因为 <code>email</code> 字段与 <code>email</code> 参数有着相同的名称,则只需编写 <code>email</code> 而不是 <code>email: email</code>。</p> <h3 id="使用结构体更新语法从其他实例创建实例"><a href="#使用结构体更新语法从其他实例创建实例" class="header-anchor">#</a> 使用结构体更新语法从其他实例创建实例</h3> <p>使用旧实例的大部分值但改变其部分值来创建一个新的结构体实例通常是很有帮助的。这可以通过 <strong>结构体更新语法</strong>(<em>struct update syntax</em>)实现。</p> <p>首先,示例 5-6 展示了不使用更新语法时,如何在 <code>user2</code> 中创建一个新 <code>User</code> 实例。我们为 <code>email</code> 和 <code>username</code> 设置了新的值,其他值则使用了实例 5-2 中创建的 <code>user1</code> 中的同名值:</p> <div class="language-rust extra-class"><pre class="language-rust"><code># <span class="token keyword">struct</span> <span class="token type-definition class-name">User</span> <span class="token punctuation">{</span>
# username<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span>
# email<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span>
# sign_in_count<span class="token punctuation">:</span> <span class="token keyword">u64</span><span class="token punctuation">,</span>
# active<span class="token punctuation">:</span> <span class="token keyword">bool</span><span class="token punctuation">,</span>
# <span class="token punctuation">}</span>
#
# <span class="token keyword">let</span> user1 <span class="token operator">=</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
# email<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"[email protected]"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
# username<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"someusername123"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
# active<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
# sign_in_count<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
# <span class="token punctuation">}</span><span class="token punctuation">;</span>
#
<span class="token keyword">let</span> user2 <span class="token operator">=</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
email<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"[email protected]"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
username<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"anotherusername567"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
active<span class="token punctuation">:</span> user1<span class="token punctuation">.</span>active<span class="token punctuation">,</span>
sign_in_count<span class="token punctuation">:</span> user1<span class="token punctuation">.</span>sign_in_count<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p><span class="caption">示例 5-6:创建 <code>User</code> 新实例,其使用了一些来自 <code>user1</code> 的值</span></p> <p>使用结构体更新语法,我们可以通过更少的代码来达到相同的效果,如示例 5-7 所示。<code>..</code> 语法指定了剩余未显式设置值的字段应有与给定实例对应字段相同的值。</p> <div class="language-rust extra-class"><pre class="language-rust"><code># <span class="token keyword">struct</span> <span class="token type-definition class-name">User</span> <span class="token punctuation">{</span>
# username<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span>
# email<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span>
# sign_in_count<span class="token punctuation">:</span> <span class="token keyword">u64</span><span class="token punctuation">,</span>
# active<span class="token punctuation">:</span> <span class="token keyword">bool</span><span class="token punctuation">,</span>
# <span class="token punctuation">}</span>
#
# <span class="token keyword">let</span> user1 <span class="token operator">=</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
# email<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"[email protected]"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
# username<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"someusername123"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
# active<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
# sign_in_count<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
# <span class="token punctuation">}</span><span class="token punctuation">;</span>
#
<span class="token keyword">let</span> user2 <span class="token operator">=</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
email<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"[email protected]"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
username<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"anotherusername567"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">..</span>user1
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p><span class="caption">示例 5-7:使用结构体更新语法为一个 <code>User</code> 实例设置新的 <code>email</code> 和 <code>username</code> 值,不过其余值来自 <code>user1</code> 变量中实例的字段</span></p> <p>示例 5-7 中的代码也在 <code>user2</code> 中创建了一个新实例,其有不同的 <code>email</code> 和 <code>username</code> 值不过 <code>active</code> 和 <code>sign_in_count</code> 字段的值与 <code>user1</code> 相同。</p> <h3 id="使用没有命名字段的元组结构体来创建不同的类型"><a href="#使用没有命名字段的元组结构体来创建不同的类型" class="header-anchor">#</a> 使用没有命名字段的元组结构体来创建不同的类型</h3> <p>也可以定义与元组(在第三章讨论过)类似的结构体,称为 <strong>元组结构体</strong>(<em>tuple structs</em>)。元组结构体有着结构体名称提供的含义,但没有具体的字段名,只有字段的类型。当你想给整个元组取一个名字,并使元组成为与其他元组不同的类型时,元组结构体是很有用的,这时像常规结构体那样为每个字段命名就显得多余和形式化了。</p> <p>要定义元组结构体,以 <code>struct</code> 关键字和结构体名开头并后跟元组中的类型。例如,下面是两个分别叫做 <code>Color</code> 和 <code>Point</code> 元组结构体的定义和用法:</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">struct</span> <span class="token type-definition class-name">Color</span><span class="token punctuation">(</span><span class="token keyword">i32</span><span class="token punctuation">,</span> <span class="token keyword">i32</span><span class="token punctuation">,</span> <span class="token keyword">i32</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">struct</span> <span class="token type-definition class-name">Point</span><span class="token punctuation">(</span><span class="token keyword">i32</span><span class="token punctuation">,</span> <span class="token keyword">i32</span><span class="token punctuation">,</span> <span class="token keyword">i32</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> black <span class="token operator">=</span> <span class="token class-name">Color</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> origin <span class="token operator">=</span> <span class="token class-name">Point</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>注意 <code>black</code> 和 <code>origin</code> 值的类型不同,因为它们是不同的元组结构体的实例。你定义的每一个结构体有其自己的类型,即使结构体中的字段有着相同的类型。例如,一个获取 <code>Color</code> 类型参数的函数不能接受 <code>Point</code> 作为参数,即便这两个类型都由三个 <code>i32</code> 值组成。在其他方面,元组结构体实例类似于元组:可以将其解构为单独的部分,也可以使用 <code>.</code> 后跟索引来访问单独的值,等等。</p> <h3 id="没有任何字段的类单元结构体"><a href="#没有任何字段的类单元结构体" class="header-anchor">#</a> 没有任何字段的类单元结构体</h3> <p>我们也可以定义一个没有任何字段的结构体!它们被称为 <strong>类单元结构体</strong>(<em>unit-like structs</em>)因为它们类似于 <code>()</code>,即 unit 类型。类单元结构体常常在你想要在某个类型上实现 trait 但不需要在类型中存储数据的时候发挥作用。我们将在第十章介绍 trait。</p> <blockquote><h3 id="结构体数据的所有权"><a href="#结构体数据的所有权" class="header-anchor">#</a> 结构体数据的所有权</h3> <p>在示例 5-1 中的 <code>User</code> 结构体的定义中,我们使用了自身拥有所有权的 <code>String</code> 类型而不是 <code>&str</code> 字符串 slice 类型。这是一个有意而为之的选择,因为我们想要这个结构体拥有它所有的数据,为此只要整个结构体是有效的话其数据也是有效的。</p> <p>可以使结构体存储被其他对象拥有的数据的引用,不过这么做的话需要用上 <strong>生命周期</strong>(<em>lifetimes</em>),这是一个第十章会讨论的 Rust 功能。生命周期确保结构体引用的数据有效性跟结构体本身保持一致。如果你尝试在结构体中存储一个引用而不指定生命周期将是无效的,比如这样:</p> <p><span class="filename">文件名: src/main.rs</span></p> <div class="language-rust,ignore,does_not_compile extra-class"><pre class="language-text"><code>struct User {
username: &str,
email: &str,
sign_in_count: u64,
active: bool,
}
fn main() {
let user1 = User {
email: "[email protected]",
username: "someusername123",
active: true,
sign_in_count: 1,
};
}
</code></pre></div><p>编译器会抱怨它需要生命周期标识符:</p> <div class="language-text extra-class"><pre class="language-text"><code>error[E0106]: missing lifetime specifier
-->
|
2 | username: &str,
| ^ expected lifetime parameter
error[E0106]: missing lifetime specifier
-->
|
3 | email: &str,
| ^ expected lifetime parameter
</code></pre></div><p>第十章会讲到如何修复这个问题以便在结构体中存储引用,不过现在,我们会使用像 <code>String</code> 这类拥有所有权的类型来替代 <code>&str</code> 这样的引用以修正这个错误。</p></blockquote></div> <footer class="page-edit" style="display:none;"><!----> <!----></footer> <!----> <!----> <!----></main> <!----></div></div></div></div><div class="global-ui"><div class="back-to-ceiling" style="right:1rem;bottom:6rem;width:2.5rem;height:2.5rem;border-radius:.25rem;line-height:2.5rem;display:none;" data-v-c6073ba8 data-v-c6073ba8><svg t="1574745035067" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5404" class="icon" data-v-c6073ba8><path d="M526.60727968 10.90185116a27.675 27.675 0 0 0-29.21455937 0c-131.36607665 82.28402758-218.69155461 228.01873535-218.69155402 394.07834331a462.20625001 462.20625001 0 0 0 5.36959153 69.94390903c1.00431239 6.55289093-0.34802892 13.13561351-3.76865779 18.80351572-32.63518765 54.11355614-51.75690182 118.55860487-51.7569018 187.94566865a371.06718723 371.06718723 0 0 0 11.50484808 91.98906777c6.53300375 25.50556257 41.68394495 28.14064038 52.69160883 4.22606766 17.37162448-37.73630017 42.14135425-72.50938081 72.80769204-103.21549295 2.18761121 3.04276886 4.15646224 6.24463696 6.40373557 9.22774369a1871.4375 1871.4375 0 0 0 140.04691725 5.34970492 1866.36093723 1866.36093723 0 0 0 140.04691723-5.34970492c2.24727335-2.98310674 4.21612437-6.18497483 6.3937923-9.2178004 30.66633723 30.70611158 55.4360664 65.4791928 72.80769147 103.21549355 11.00766384 23.91457269 46.15860503 21.27949489 52.69160879-4.22606768a371.15156223 371.15156223 0 0 0 11.514792-91.99901164c0-69.36717486-19.13165746-133.82216804-51.75690182-187.92578088-3.42062944-5.66790279-4.76302748-12.26056868-3.76865837-18.80351632a462.20625001 462.20625001 0 0 0 5.36959269-69.943909c-0.00994388-166.08943902-87.32547796-311.81420293-218.6915546-394.09823051zM605.93803103 357.87693858a93.93749974 93.93749974 0 1 1-187.89594924 6.1e-7 93.93749974 93.93749974 0 0 1 187.89594924-6.1e-7z" p-id="5405" data-v-c6073ba8></path><path d="M429.50777625 765.63860547C429.50777625 803.39355007 466.44236686 1000.39046097 512.00932183 1000.39046097c45.56695499 0 82.4922232-197.00623328 82.5015456-234.7518555 0-37.75494459-36.9345906-68.35043303-82.4922232-68.34111062-45.57627738-0.00932239-82.52019037 30.59548842-82.51086798 68.34111062z" p-id="5406" data-v-c6073ba8></path></svg></div></div></div>
<script src="/assets/js/app.e6b14c5e.js" defer></script><script src="/assets/js/3.ecc21787.js" defer></script><script src="/assets/js/1.032ec45e.js" defer></script><script src="/assets/js/38.9aaa7af9.js" defer></script>
</body>
</html>