-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
457 lines (241 loc) · 164 KB
/
atom.xml
File metadata and controls
457 lines (241 loc) · 164 KB
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>kimroniny</title>
<link href="http://www.kimroniny.top/atom.xml" rel="self"/>
<link href="http://www.kimroniny.top/"/>
<updated>2023-08-07T00:17:53.081Z</updated>
<id>http://www.kimroniny.top/</id>
<author>
<name>kimroniny</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>wsl-代理问题</title>
<link href="http://www.kimroniny.top/2023/07/28/wsl-%E4%BB%A3%E7%90%86%E9%97%AE%E9%A2%98/"/>
<id>http://www.kimroniny.top/2023/07/28/wsl-%E4%BB%A3%E7%90%86%E9%97%AE%E9%A2%98/</id>
<published>2023-07-28T02:28:14.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>wsl 设置代理时遇到的问题</p><span id="more"></span><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">export</span> HTTP_PROXY=http://<span class="variable">${cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }</span><span class="string">'}:7890</span></span><br><span class="line"><span class="string">export HTTPS_PROXY=http://${cat /etc/resolv.conf | grep nameserver | awk '</span>{ <span class="built_in">print</span> <span class="variable">$2</span> }<span class="string">'}:7890</span></span><br></pre></td></tr></table></figure><p>如果无法访问宿主机ip, 可能是因为宿主机的防火墙没有打开</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">New-NetFirewallRule -DisplayName <span class="string">"WSL"</span> -Direction Inbound -InterfaceAlias <span class="string">"vEthernet (WSL)"</span> -Action Allow</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>wsl 设置代理时遇到的问题</p></summary>
<category term="wsl" scheme="http://www.kimroniny.top/categories/wsl/"/>
<category term="wsl" scheme="http://www.kimroniny.top/tags/wsl/"/>
</entry>
<entry>
<title>rust教程-08</title>
<link href="http://www.kimroniny.top/2022/11/13/rust%E6%95%99%E7%A8%8B-08/"/>
<id>http://www.kimroniny.top/2022/11/13/rust%E6%95%99%E7%A8%8B-08/</id>
<published>2022-11-13T10:04:45.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>rust 教程 07: vector, string, hashmap</p><span id="more"></span><h2 id="vector"><a class="markdownIt-Anchor" href="#vector"></a> Vector</h2><h3 id="vector-的基本使用"><a class="markdownIt-Anchor" href="#vector-的基本使用"></a> vector 的基本使用</h3><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="comment">// 必须要指明类型,或者通过 push,能够让编译器知道 v 的类型</span></span><br><span class="line"> <span class="comment">// 离开作用域的时候,v 就被删除了</span></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">v</span>: <span class="type">Vec</span><<span class="type">i32</span>> = <span class="type">Vec</span>::<span class="title function_ invoke__">new</span>();</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 不用显示指明类型</span></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">v2</span> = <span class="built_in">vec!</span>[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>];</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 因为 push 了一个 i32 类型的数据,所以不需要显示地指明类型</span></span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">v3</span> = <span class="type">Vec</span>::<span class="title function_ invoke__">new</span>();</span><br><span class="line"> v3.<span class="title function_ invoke__">push</span>(<span class="number">1</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// -------</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// 两种读取 vector 元素的方法</span></span><br><span class="line"> <span class="comment">// 1. 通过索引</span></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">x</span> = &v2[<span class="number">1</span>];</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 2. 通过 get 方法</span></span><br><span class="line"> <span class="keyword">match</span> v2.<span class="title function_ invoke__">get</span>(<span class="number">1</span>) {</span><br><span class="line"> <span class="title function_ invoke__">Some</span>(x) => {</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"x is: {}"</span>, x);</span><br><span class="line"> },</span><br><span class="line"> <span class="literal">None</span> => {</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"x is None"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// -------</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// 不能在同一作用域内同时拥有可变和不可变引用</span></span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">v4</span> = <span class="type">Vec</span>::<span class="title function_ invoke__">new</span>();</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">first</span> = &v4[<span class="number">1</span>]; <span class="comment">// 不可变借用</span></span><br><span class="line"> v4.<span class="title function_ invoke__">push</span>(<span class="number">10</span>); <span class="comment">// 可变借用,和上面的不可变借用发生冲突,</span></span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"first is {}"</span>, first);</span><br><span class="line"> <span class="comment">// 因为 push 的过程如果 vector 内存不够,则导致 vector 重新分配内润地址,所以此时不可变借用就失效了,因此编译器不允许这种情况出现</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// -------</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// for 循环</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">v5</span> = <span class="built_in">vec!</span>[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>];</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> <span class="variable">i</span> <span class="keyword">in</span> &<span class="keyword">mut</span> v5 {</span><br><span class="line"> *i += <span class="number">10</span>; <span class="comment">// 修改 v5 的值</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> <span class="variable">i</span> <span class="keyword">in</span> &v5 { <span class="comment">// 循环打印</span></span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"i is {}"</span>, i);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"Hello, world!"</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="vector-的例子"><a class="markdownIt-Anchor" href="#vector-的例子"></a> vector 的例子</h3><p>使用 enum 改变 vector 元素的类型</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">enum</span> <span class="title class_">SheetCell</span> {</span><br><span class="line"> <span class="title function_ invoke__">Int</span>(<span class="type">i32</span>),</span><br><span class="line"> <span class="title function_ invoke__">Float</span>(<span class="type">f64</span>),</span><br><span class="line"> <span class="title function_ invoke__">Text</span>(<span class="type">String</span>),</span><br><span class="line">}</span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">row</span> = <span class="built_in">vec!</span>[</span><br><span class="line"> SheetCell::<span class="title function_ invoke__">Int</span>(<span class="number">1</span>),</span><br><span class="line"> SheetCell::<span class="title function_ invoke__">Float</span>(<span class="number">10.0</span>),</span><br><span class="line"> SheetCell::<span class="title function_ invoke__">Text</span>(<span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"asdasd"</span>)),</span><br><span class="line"> ];</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="string"><a class="markdownIt-Anchor" href="#string"></a> String</h2><p>rust 的核心语言层面,只有一个字符串类型,即字符串切片 str 或者 &str,对存储在其他地方、UTF-8编码的字符串的引用</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="comment">// -------</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// 创建字符串类型的几种方法</span></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">s</span> = <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"asdasd"</span>);</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">s1</span> = <span class="string">"adadad"</span>.<span class="title function_ invoke__">to_string</span>();</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">data</span> = <span class="string">"dasdad"</span>;</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">s2</span> = data.<span class="title function_ invoke__">to_string</span>();</span><br><span class="line"></span><br><span class="line"> <span class="comment">// -------</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment">// 更新 string</span></span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">s3</span> = <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"asdada"</span>);</span><br><span class="line"> s3.<span class="title function_ invoke__">push_str</span>(<span class="string">"asdadasd"</span>);</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">s4</span> = <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"sdasd"</span>);</span><br><span class="line"> s3.<span class="title function_ invoke__">push_str</span>(&s4); <span class="comment">// 不会改变 s4 的所有权</span></span><br><span class="line"> s3.<span class="title function_ invoke__">push</span>(<span class="string">'1'</span>); <span class="comment">// 附加一个字符</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// 取得了 s3 的所有权,s3会失效</span></span><br><span class="line"> <span class="comment">// &s4 被强制转换为字符串切片 &str,解引用强制类型转换</span></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">s5</span> = s3+&s4; </span><br><span class="line"></span><br><span class="line"> <span class="comment">// 可以直接用 format 来构建新字符串,这样不会改变所有权</span></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">s5</span> = <span class="built_in">format!</span>(<span class="string">"{}-{}-{}"</span>, s1, s2, s5);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// -------</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// 访问字符串元素</span></span><br><span class="line"> <span class="comment">// String 不支持索引形式访问元素</span></span><br><span class="line"> <span class="comment">// String 是对 vec<u8> 的包装</span></span><br><span class="line"> <span class="comment">// 由于 String 是一种 utF-8 编码,所以索引的位置指代的不一定就是字符的位置,有可能是某个字节</span></span><br><span class="line"> <span class="keyword">for</span> <span class="variable">w</span> <span class="keyword">in</span> s5.<span class="title function_ invoke__">chars</span>() { <span class="comment">// 获得标量值</span></span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"{}"</span>, w);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span> <span class="variable">w</span> <span class="keyword">in</span> s5.<span class="title function_ invoke__">bytes</span>() { <span class="comment">// 获得字节</span></span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"{}"</span>, w);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 字符串切片</span></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">s6</span> = &s5[<span class="number">0</span>..<span class="number">4</span>]; <span class="comment">// 必须沿着字符的边界进行切割(比如一个字符占两个字节),否则就会 panic</span></span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="hashmapk-v"><a class="markdownIt-Anchor" href="#hashmapk-v"></a> HashMap<K, V></h2><p>以键值对的形式存储数据,一个键对应一个值</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">use</span> std::collections::HashMap;</span><br><span class="line"></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"></span><br><span class="line"> <span class="comment">// -----------</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// hashmap 是同构的,即 k 必须是同一类型,v 必须是同一类型</span></span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">scores</span> = HashMap::<span class="title function_ invoke__">new</span>();</span><br><span class="line"> scores.<span class="title function_ invoke__">insert</span>(<span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"asdads"</span>), <span class="number">10</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 通过 collect 来创建 hashmap</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">teams</span> = <span class="built_in">vec!</span>[</span><br><span class="line"> <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"asdad"</span>),</span><br><span class="line"> <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"agdfgd"</span>),</span><br><span class="line"> ];</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">initial_scores</span> = <span class="built_in">vec!</span>[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>];</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">scores</span>: HashMap<_,_> = <span class="comment">// 用下划线是因为编译器可以根据 vector 中的元素推导出 k v 的类型</span></span><br><span class="line"> teams.<span class="title function_ invoke__">iter</span>().<span class="title function_ invoke__">zip</span>(initial_scores.<span class="title function_ invoke__">iter</span>()).<span class="title function_ invoke__">collect</span>();</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 所有权问题</span></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">s1</span> = <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"asdasd"</span>);</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">s2</span> = <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"asdasd"</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">map</span> = HashMap::<span class="title function_ invoke__">new</span>();</span><br><span class="line"> map.<span class="title function_ invoke__">insert</span>(&s1, &s2); <span class="comment">// 传递引用不会改变所有权</span></span><br><span class="line"> <span class="comment">// map.insert(s1, s2); // 会改变 s1 和 s2 的所有权</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// 通过 get 取得 hashmap 的值</span></span><br><span class="line"> <span class="keyword">match</span> map.<span class="title function_ invoke__">get</span>(&<span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"asdas"</span>)) {</span><br><span class="line"> <span class="title function_ invoke__">Some</span>(x) => {</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"{}"</span>, x);</span><br><span class="line"> },</span><br><span class="line"> <span class="literal">None</span> => {</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"None"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 通过 for 循环遍历 hashmap 的值</span></span><br><span class="line"> <span class="title function_ invoke__">for</span> (k,v) <span class="keyword">in</span> &map {</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"{}, {}"</span>, k, v);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 更新 hashmap</span></span><br><span class="line"> <span class="comment">// 每个 k 同时只能对应一个 v</span></span><br><span class="line"> <span class="comment">// 更新 hashmap 中的数据</span></span><br><span class="line"> <span class="comment">// 1. k 已经存在,对应一个 v</span></span><br><span class="line"> <span class="comment">// - 替换现有的 v</span></span><br><span class="line"> <span class="comment">// - 保留现有的 v,忽略新的 v</span></span><br><span class="line"> <span class="comment">// - 合并现有的 v 和新的 v</span></span><br><span class="line"> <span class="comment">// 2. k 不存在</span></span><br><span class="line"> <span class="comment">// - 添加一对 (k, v)</span></span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">scores</span> = HashMap::<span class="title function_ invoke__">new</span>();</span><br><span class="line"> scores.<span class="title function_ invoke__">insert</span>(<span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"asdsd"</span>), <span class="number">10</span>);</span><br><span class="line"> scores.<span class="title function_ invoke__">insert</span>(<span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"asdsd"</span>), <span class="number">12</span>); <span class="comment">// asdsd 的值已经改为 12,无论值是否存在,都在被设置为 12 </span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// 对于 entry 而言</span></span><br><span class="line"> <span class="comment">// 如果 k 存在,则返回对应的 v 的一个可变引用</span></span><br><span class="line"> <span class="comment">// 如果 k 不存在,则将新的值插入进去,然后返回该值的可变引用</span></span><br><span class="line"> scores.<span class="title function_ invoke__">entry</span>(<span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"asdsd"</span>)).<span class="title function_ invoke__">or_insert</span>(<span class="number">49</span>); <span class="comment">// 如果不存在则插入并返回新值的引用,如果存在则返回已有的值的引用</span></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">e</span> = scores.<span class="title function_ invoke__">entry</span>(<span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"asdsd"</span>));</span><br><span class="line"> e.<span class="title function_ invoke__">or_insert</span>(<span class="number">666</span>);</span><br><span class="line"> </span><br><span class="line"> <span class="comment">// 基于现有的值 v 来更新</span></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">text</span> = <span class="string">"asdasd adfs asdsd asda"</span>;</span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">map</span> = HashMap::<span class="title function_ invoke__">new</span>();</span><br><span class="line"> <span class="keyword">for</span> <span class="variable">word</span> <span class="keyword">in</span> text.<span class="title function_ invoke__">split_whitespace</span>() {</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">count</span>: &<span class="keyword">mut</span> <span class="type">i32</span> = map.<span class="title function_ invoke__">entry</span>(word).<span class="title function_ invoke__">or_insert</span>(<span class="number">0</span>);</span><br><span class="line"> *count += <span class="number">1</span>; <span class="comment">// 注意 count 是一个可变引用</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>rust 教程 07: vector, string, hashmap</p></summary>
<category term="rust" scheme="http://www.kimroniny.top/categories/rust/"/>
<category term="rust" scheme="http://www.kimroniny.top/tags/rust/"/>
</entry>
<entry>
<title>rust教程-07</title>
<link href="http://www.kimroniny.top/2022/11/13/rust%E6%95%99%E7%A8%8B-07/"/>
<id>http://www.kimroniny.top/2022/11/13/rust%E6%95%99%E7%A8%8B-07/</id>
<published>2022-11-13T08:31:00.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>rust 教程 07: 包</p><span id="more"></span><h2 id="package-和-crate"><a class="markdownIt-Anchor" href="#package-和-crate"></a> package 和 crate</h2><p>crate 的类型:</p><ul><li>binary</li><li>library</li></ul><p>crate root:</p><ul><li>源代码文件</li><li>rust 编译器从这里开始,组成 crate 的根 module</li></ul><p>package:</p><ul><li>包含 1 个 crate.toxl,他描述了如何构建这些 crates</li><li>只能包含 0-1 个 library crate</li><li>可以包含任意数量的 binary crate</li><li>但必须至少包含一个 crate(library 或者 binary)</li></ul><p>cargo 的惯例:</p><ul><li>src/main.rs:binary crate<ul><li>bianry crate 的 crate root</li><li>crate 名与 package 名相同</li></ul></li><li>src/lib.rs:library crate<ul><li>package 包含一个 library code</li><li>library crate 的 crate root</li><li>crate 名与 package 名相同</li></ul></li><li>crago 把 crate root 文件交给 rustc 来构建 library 或者 binary</li><li>一个 package 可以同时包含 src/main.rs 和 src/lib.rs</li><li>一个 package 可以有多个 binary crate</li></ul><h2 id="module"><a class="markdownIt-Anchor" href="#module"></a> Module</h2><p>Module:</p><ul><li>在一个 crate 内,将代码进行分组</li><li>增加可读性</li><li>控制项目的私有性:public、private</li></ul><p>建立 module:</p><ul><li>mod 关键字</li><li>可嵌套</li><li>可以包含其他项的定义</li></ul><h2 id="path-路径"><a class="markdownIt-Anchor" href="#path-路径"></a> path 路径</h2><p>为了在 rust 的模块中找到某个条目,需要使用路径,两种形式:</p><ul><li>绝对路径:从 crate root 开始,使用 crate 名或者字面值 crate</li><li>相对路径:从当前模块开始,使用 self、super 或者当前模块的标识符</li><li>路径至少由一个标识符组成,标识符之间使用 ::</li></ul><h2 id="私有性"><a class="markdownIt-Anchor" href="#私有性"></a> 私有性</h2><ul><li>模块不仅可以组织代码,还可以定义私有边界</li><li>如果想把函数或者 struct 等设为私有,可以将其放到某个模块中</li><li>rust 中所有的条目(函数、方法、struct、enum、模块、常量)等默认都是私有的</li><li>父级模块无法访问子模块中的私有条目</li><li>子模块可以使用所有祖先模块中的条目</li></ul><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">mod</span> front_of_house {</span><br><span class="line"> <span class="comment">// 声明为公共的</span></span><br><span class="line"> <span class="keyword">pub</span> <span class="keyword">mod</span> hosting {</span><br><span class="line"> <span class="keyword">fn</span> <span class="title function_">add_to_waitlist</span>() {}</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">pub</span> <span class="keyword">fn</span> <span class="title function_">eat_at_restaurant</span>() {</span><br><span class="line"> <span class="comment">// 绝对路径</span></span><br><span class="line"> crate::front_of_house::hosting::<span class="title function_ invoke__">add_to_waitlist</span>();</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 相对路径</span></span><br><span class="line"> front_of_house::hosting::<span class="title function_ invoke__">add_to_waitlist</span>();</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="super-关键字"><a class="markdownIt-Anchor" href="#super-关键字"></a> super 关键字</h2><p>访问父级模块或者方法</p><h2 id="pub-struct"><a class="markdownIt-Anchor" href="#pub-struct"></a> pub struct</h2><ul><li>struct 是公共的</li><li>struct 的字段默认是私有的</li><li>想把哪个字段设置为公有的,就在其前面设置为 pub</li></ul><h2 id="pub-enum"><a class="markdownIt-Anchor" href="#pub-enum"></a> pub enum:</h2><ul><li>enum 是公共的</li><li>所有元素也是公共的,不需要单独设置为 pub</li></ul><h2 id="use-关键字"><a class="markdownIt-Anchor" href="#use-关键字"></a> use 关键字</h2><ul><li>对于函数,引入到父级,即上一级即可;</li><li>对于 struct、enum,引入到同一级;</li><li>也就是对于同名条目,引入到父级即可</li><li>使用 use 导入到作用域内后,该名称在该作用域内是私有的<ul><li>使用 pub use 重导出,外部代码就可以引入到他们的作用域</li></ul></li></ul><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">mod</span> front_of_house {</span><br><span class="line"> <span class="keyword">pub</span> <span class="keyword">mod</span> hosting {</span><br><span class="line"> <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="title function_">add_to_waitlist</span>() {}</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用绝对路径引入 hosting</span></span><br><span class="line"><span class="comment">// 使用 as 搞个别名</span></span><br><span class="line"><span class="keyword">use</span> crate::front_of_house::hosting <span class="keyword">as</span> hosting1;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用相对路径引入 hosting</span></span><br><span class="line"><span class="comment">// 针对函数,一般是引入到上一级,避免引入多个相同名字的函数</span></span><br><span class="line"><span class="keyword">use</span> front_of_house::hosting <span class="keyword">as</span> hosting2;</span><br><span class="line"></span><br><span class="line"><span class="keyword">pub</span> <span class="keyword">fn</span> <span class="title function_">eat_at_restaurant</span>() {</span><br><span class="line"> <span class="comment">// 绝对路径</span></span><br><span class="line"> crate::front_of_house::hosting::<span class="title function_ invoke__">add_to_waitlist</span>();</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 相对路径</span></span><br><span class="line"> front_of_house::hosting::<span class="title function_ invoke__">add_to_waitlist</span>();</span><br><span class="line"></span><br><span class="line"> hosting::<span class="title function_ invoke__">add_to_waitlist</span>();</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="使用外部包-package"><a class="markdownIt-Anchor" href="#使用外部包-package"></a> 使用外部包 package</h2><ul><li>cargo.toml 添加依赖的包 package</li><li>use 将特定条目引入到作用域</li><li>std 包不需要放入到 c</li></ul><p>cargo.toml 中</p><p>使用嵌套路径来引入相同 package 下的多个条目</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">use</span> std:: {</span><br><span class="line"> cmd::Ordering,</span><br><span class="line"> io</span><br><span class="line">};</span><br><span class="line"><span class="keyword">use</span> std::io{</span><br><span class="line"> <span class="keyword">self</span>, <span class="comment">// 引入自己</span></span><br><span class="line"> write</span><br><span class="line">};</span><br></pre></td></tr></table></figure><h2 id="将模块内容移动到其他文件"><a class="markdownIt-Anchor" href="#将模块内容移动到其他文件"></a> 将模块内容移动到其他文件</h2><p>模块定义时,如果模块后边是 “;”,而不是代码块:</p><ul><li>rust 会从与模块同名的文件中加载内容</li><li>模块树的结构不会变化</li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">src/</span><br><span class="line">├── front_of_house</span><br><span class="line">│ └── hosting.rs</span><br><span class="line">├── front_of_house.rs</span><br><span class="line">├── lib.rs</span><br><span class="line">└── main.rs</span><br></pre></td></tr></table></figure><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// src/front_of_house.rs</span></span><br><span class="line"><span class="keyword">pub</span> <span class="keyword">mod</span> hosting; <span class="comment">// 依旧要声明为 pub,公有类型</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// src/front_of_house/hosting.rs</span></span><br><span class="line"><span class="keyword">pub</span> <span class="keyword">fn</span> <span class="title function_">add_to_waitlist</span>() {}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>rust 教程 07: 包</p></summary>
<category term="rust" scheme="http://www.kimroniny.top/categories/rust/"/>
<category term="rust" scheme="http://www.kimroniny.top/tags/rust/"/>
</entry>
<entry>
<title>rust教程-06</title>
<link href="http://www.kimroniny.top/2022/11/01/rust%E6%95%99%E7%A8%8B-06/"/>
<id>http://www.kimroniny.top/2022/11/01/rust%E6%95%99%E7%A8%8B-06/</id>
<published>2022-11-01T12:27:44.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>rust 教程 06: 枚举</p><span id="more"></span><h2 id="枚举"><a class="markdownIt-Anchor" href="#枚举"></a> 枚举</h2><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#[derive(Debug)]</span></span><br><span class="line"><span class="keyword">enum</span> <span class="title class_">Message</span> {</span><br><span class="line"> Quit, <span class="comment">// 可以不指定类型</span></span><br><span class="line"> Move { x: <span class="type">i32</span>, y: <span class="type">i32</span>}, <span class="comment">// 可以是一个结构体</span></span><br><span class="line"> <span class="title function_ invoke__">Write</span> (<span class="type">String</span>), <span class="comment">// 可以是一个 String</span></span><br><span class="line"> <span class="title function_ invoke__">ChangeColor</span> (<span class="type">i32</span>, <span class="type">i32</span>, <span class="type">i32</span>), <span class="comment">// 可以是一个 tuple</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">impl</span> <span class="title class_">Message</span> { <span class="comment">// 为枚举类型添加方法</span></span><br><span class="line"> <span class="keyword">fn</span> <span class="title function_">call</span>(&<span class="keyword">self</span>) {</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"{:#?}"</span>, <span class="keyword">self</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">q</span> = Message::Quit;</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">m</span> = Message::Move { x: <span class="number">19</span>, y: <span class="number">29</span> };</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">w</span> = Message::<span class="title function_ invoke__">Write</span>(<span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"asdasd"</span>));</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">c</span> = Message::<span class="title function_ invoke__">ChangeColor</span>(<span class="number">12</span>, <span class="number">12</span>, <span class="number">12</span>);</span><br><span class="line"> q.<span class="title function_ invoke__">call</span>();</span><br><span class="line"> m.<span class="title function_ invoke__">call</span>();</span><br><span class="line"> w.<span class="title function_ invoke__">call</span>();</span><br><span class="line"> c.<span class="title function_ invoke__">call</span>();</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="option-类型"><a class="markdownIt-Anchor" href="#option-类型"></a> Option 类型</h2><p>rust 中没有 null</p><p>在其他语言中,一个变量可以处于两种状态:空值(null)、非空</p><p>但是当你尝试使用非 null 值那样使用 null 值的时候,就会引起某种错误</p><p>rust 中类似 null 的枚举:Option<T>,定义为:</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">enum</span> <span class="title class_">Option</span><T> {</span><br><span class="line"> <span class="title function_ invoke__">Some</span>(T),</span><br><span class="line"> <span class="literal">None</span>,</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>基本的使用方法:</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">some_num</span> = <span class="title function_ invoke__">Some</span>(<span class="number">5</span>);</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">some_str</span> = <span class="title function_ invoke__">Some</span>(<span class="string">"asdasd"</span>);</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">some_none</span>:<span class="type">Option</span><<span class="type">i32</span>> = <span class="literal">None</span>; <span class="comment">// 必须显示的指定类型</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>在 rust 中,Option<T> 和 T 是不同的类型,不可以直接相操作</p><h2 id="match"><a class="markdownIt-Anchor" href="#match"></a> match</h2><p>模式匹配,类似于 switch</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#[derive(Debug)]</span></span><br><span class="line"><span class="keyword">enum</span> <span class="title class_">UsState</span> {</span><br><span class="line"> Washington,</span><br><span class="line"> NewYork,</span><br><span class="line">}</span><br><span class="line"><span class="keyword">enum</span> <span class="title class_">Coin</span> {</span><br><span class="line"> Penny,</span><br><span class="line"> Nickel,</span><br><span class="line"> Dime,</span><br><span class="line"> <span class="title function_ invoke__">Quarter</span>(UsState),</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">match_coin</span>(coin: &Coin) <span class="punctuation">-></span> <span class="type">i8</span>{</span><br><span class="line"> <span class="keyword">match</span> coin { <span class="comment">// 必须列出所有可能的值,如果不想列出,必须用 _ 代替</span></span><br><span class="line"> Coin::Penny => { <span class="comment">// 使用 => </span></span><br><span class="line"> <span class="number">10</span></span><br><span class="line"> },</span><br><span class="line"> Coin::Nickel => {</span><br><span class="line"> <span class="number">20</span></span><br><span class="line"> },</span><br><span class="line"> Coin::Dime => <span class="number">5</span>, <span class="comment">// 也可以不跟 {}</span></span><br><span class="line"> Coin::<span class="title function_ invoke__">Quarter</span>(state) => { <span class="comment">// 匹配某种类型的枚举值</span></span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"{:#?}"</span>, state);</span><br><span class="line"> <span class="number">100</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">coin</span> = Coin::Penny;</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">coin2</span> = Coin::<span class="title function_ invoke__">Quarter</span>(UsState::NewYork);</span><br><span class="line"> <span class="title function_ invoke__">match_coin</span>(&coin);</span><br><span class="line"> <span class="title function_ invoke__">match_coin</span>(&coin2);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>用于 Option<T> 的匹配时</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">five</span> = <span class="title function_ invoke__">Some</span>(<span class="number">5</span>);</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">six</span> = <span class="literal">None</span>;</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"{:#?}"</span>, <span class="title function_ invoke__">inc</span>(five));</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"{:#?}"</span>, <span class="title function_ invoke__">inc</span>(six));</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">inc</span>(value: <span class="type">Option</span><<span class="type">i32</span>>) <span class="punctuation">-></span> <span class="type">Option</span><<span class="type">i32</span>> {</span><br><span class="line"> <span class="keyword">match</span> value {</span><br><span class="line"> <span class="title function_ invoke__">Some</span>(i)=> {</span><br><span class="line"> <span class="title function_ invoke__">Some</span>(i+<span class="number">1</span>)</span><br><span class="line"> },</span><br><span class="line"> <span class="literal">None</span> => { <span class="comment">// 必须要穷举所有的可能性</span></span><br><span class="line"> <span class="literal">None</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="if-let"><a class="markdownIt-Anchor" href="#if-let"></a> if let</h2><p><code>if let</code> 用于匹配一种情况</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">three</span> = <span class="title function_ invoke__">Some</span>(<span class="number">3</span>);</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">let</span> <span class="variable">Some</span>(<span class="number">3</span>) = three { <span class="comment">// 注意这里用的是一个等号</span></span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"{}"</span>, <span class="number">3</span>);</span><br><span class="line"> } <span class="keyword">else</span> { <span class="comment">// 也可以使用 else 来指定其他情况的处理逻辑</span></span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"others"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>rust 教程 06: 枚举</p></summary>
<category term="rust" scheme="http://www.kimroniny.top/categories/rust/"/>
<category term="rust" scheme="http://www.kimroniny.top/tags/rust/"/>
</entry>
<entry>
<title>screen 基本用法</title>
<link href="http://www.kimroniny.top/2022/10/30/screen-%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/"/>
<id>http://www.kimroniny.top/2022/10/30/screen-%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/</id>
<published>2022-10-30T06:21:16.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>screen 的基本用法</p><span id="more"></span><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">yum install screen</span><br><span class="line"></span><br><span class="line">screen -S name python test.py <span class="comment"># screen -S <name> <cmd></span></span><br><span class="line"></span><br><span class="line">Ctrl a+d <span class="comment"># 从 screen 中退出,但是不中断 screen</span></span><br><span class="line"></span><br><span class="line">screen -r name <span class="comment"># 回到名称为 name 的 screen</span></span><br><span class="line"></span><br><span class="line">screen -d name <span class="comment"># 将名称为 name 的 screen 离线</span></span><br><span class="line"></span><br><span class="line">screen -<span class="built_in">ls</span> <span class="comment"># 查看所有的 screen </span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>screen 的基本用法</p></summary>
<category term="linux" scheme="http://www.kimroniny.top/categories/linux/"/>
<category term="linux" scheme="http://www.kimroniny.top/tags/linux/"/>
<category term="screen" scheme="http://www.kimroniny.top/tags/screen/"/>
</entry>
<entry>
<title>rust教程-05</title>
<link href="http://www.kimroniny.top/2022/10/25/rust%E6%95%99%E7%A8%8B-05/"/>
<id>http://www.kimroniny.top/2022/10/25/rust%E6%95%99%E7%A8%8B-05/</id>
<published>2022-10-25T15:12:51.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>rust 教程 05: struct</p><span id="more"></span><h2 id="struct-基础内容"><a class="markdownIt-Anchor" href="#struct-基础内容"></a> struct 基础内容</h2><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">User</span> {</span><br><span class="line"> username: <span class="type">String</span>,</span><br><span class="line"> email: <span class="type">String</span>,</span><br><span class="line"> active: <span class="type">bool</span>, <span class="comment">// 最后一个字段也要有逗号</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">build_user</span>(username: <span class="type">String</span>, email: <span class="type">String</span>, active: <span class="type">bool</span>) <span class="punctuation">-></span> User { <span class="comment">// 函数返回结构体</span></span><br><span class="line"> User {</span><br><span class="line"> username, <span class="comment">// 可以使用简写的方式初始化,只要变量名和字段名相同即可</span></span><br><span class="line"> email,</span><br><span class="line"> active</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="comment">// 声明了可变的user,此时 user 的所有变量都是可变的</span></span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">user</span> = User {</span><br><span class="line"> active: <span class="literal">true</span>,</span><br><span class="line"> email: <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"kimroniny@gmail.com"</span>),</span><br><span class="line"> username: <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"kimroniny"</span>) <span class="comment">// 可以调整赋值顺序,但是不可以不给某个字段赋值</span></span><br><span class="line"> };</span><br><span class="line"> user.active = <span class="literal">false</span>; <span class="comment">// 修改字段的值;</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">user2</span> = User {</span><br><span class="line"> email: <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"cuncun@gmail.com"</span>),</span><br><span class="line"> ..user</span><br><span class="line"> }; <span class="comment">// 使用已有的 user 为新的 user2 赋值</span></span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"Hello, world!"</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="tuple-struct"><a class="markdownIt-Anchor" href="#tuple-struct"></a> tuple struct</h2><p>类似于 tuple 的 struct,整体有个名字,但是字段没有名字,只有类型</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="keyword">struct</span> <span class="title class_">Color</span>(<span class="type">i32</span>,<span class="type">i32</span>,<span class="type">i32</span>);</span><br><span class="line"> <span class="keyword">struct</span> <span class="title class_">Point</span>(<span class="type">i32</span>,<span class="type">i32</span>,<span class="type">i32</span>);</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">color</span> = <span class="title function_ invoke__">Color</span>(<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>); <span class="comment">// 初始化方式和 struct 不一样,用 ()</span></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">origin</span> = <span class="title function_ invoke__">Point</span>(<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="struct-的一个例子"><a class="markdownIt-Anchor" href="#struct-的一个例子"></a> struct 的一个例子</h2><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#[derive(Debug)]</span></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Rectangle</span> {</span><br><span class="line"> width: <span class="type">u32</span>,</span><br><span class="line"> length: <span class="type">u32</span>,</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">rect</span> = Rectangle {</span><br><span class="line"> width: <span class="number">1</span>,</span><br><span class="line"> length: <span class="number">2</span>,</span><br><span class="line"> };</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"area: {}"</span>, <span class="title function_ invoke__">area</span>(&rect));</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"{:?}"</span>, rect); </span><br><span class="line"> <span class="comment">/*</span></span><br><span class="line"><span class="comment"> Rectangle { width: 1, length: 2 }</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"{:#?}"</span>, rect);</span><br><span class="line"> <span class="comment">/* </span></span><br><span class="line"><span class="comment"> Rectangle {</span></span><br><span class="line"><span class="comment"> width: 1,</span></span><br><span class="line"><span class="comment"> length: 2,</span></span><br><span class="line"><span class="comment"> }</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">area</span>(rect: &Rectangle) <span class="punctuation">-></span> <span class="type">u32</span> {</span><br><span class="line"> rect.width * rect.length</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="struct-的方法"><a class="markdownIt-Anchor" href="#struct-的方法"></a> struct 的方法</h2><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#[derive(Debug)]</span></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Rectangle</span> {</span><br><span class="line"> width: <span class="type">u32</span>,</span><br><span class="line"> length: <span class="type">u32</span>,</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">impl</span> <span class="title class_">Rectangle</span> { <span class="comment">// 使用 impl 实现 struct 的方法</span></span><br><span class="line"> <span class="keyword">fn</span> <span class="title function_">area</span>(&<span class="keyword">self</span>) <span class="punctuation">-></span> <span class="type">u32</span> { </span><br><span class="line"> <span class="keyword">self</span>.width * <span class="keyword">self</span>.length</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 关联函数,第一个参数不是 self</span></span><br><span class="line"> <span class="comment">// 多用于实例化</span></span><br><span class="line"> <span class="keyword">fn</span> <span class="title function_">square</span>(size: <span class="type">u32</span>) <span class="punctuation">-></span> Rectangle {</span><br><span class="line"> Rectangle { width: size, length: size }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">impl</span> <span class="title class_">Rectangle</span> {</span><br><span class="line"> <span class="comment">// 可以放置多个 impl 块</span></span><br><span class="line"> <span class="comment">// 相当于综合在一起</span></span><br><span class="line"> <span class="keyword">fn</span> <span class="title function_">area2</span>(&<span class="keyword">self</span>) <span class="punctuation">-></span> <span class="type">u32</span> { </span><br><span class="line"> <span class="keyword">self</span>.width * <span class="keyword">self</span>.length</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">rect</span> = Rectangle {</span><br><span class="line"> width: <span class="number">1</span>,</span><br><span class="line"> length: <span class="number">2</span>,</span><br><span class="line"> };</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"area: {}"</span>, rect.<span class="title function_ invoke__">area</span>()); <span class="comment">// 直接调用</span></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">rect2</span> = Rectangle::<span class="title function_ invoke__">square</span>(<span class="number">10</span>); <span class="comment">// 使用双冒号来调用关联函数</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr /><h2 id="参考"><a class="markdownIt-Anchor" href="#参考"></a> 参考</h2><ol><li><a href="https://www.youtube.com/watch?v=e3-2uxHhbzs&list=PL3azK8C0kje1DUJbaOqce19j3R_-tIc4_&index=1&t=140s">https://www.youtube.com/watch?v=e3-2uxHhbzs&list=PL3azK8C0kje1DUJbaOqce19j3R_-tIc4_&index=1&t=140s</a></li><li>《rust权威指南(The Rust Programming Language)》</li></ol>]]></content>
<summary type="html"><p>rust 教程 05: struct</p></summary>
<category term="rust" scheme="http://www.kimroniny.top/categories/rust/"/>
<category term="rust" scheme="http://www.kimroniny.top/tags/rust/"/>
</entry>
<entry>
<title>rust教程-04</title>
<link href="http://www.kimroniny.top/2022/10/24/rust%E6%95%99%E7%A8%8B-04/"/>
<id>http://www.kimroniny.top/2022/10/24/rust%E6%95%99%E7%A8%8B-04/</id>
<published>2022-10-24T11:32:18.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>rust 教程 04: 所有权</p><span id="more"></span><h2 id="什么是所有权"><a class="markdownIt-Anchor" href="#什么是所有权"></a> 什么是所有权?</h2><p>rust 的核心特性就是<strong>所有权</strong></p><p>所有程序在运行时都必须管理它们使用计算机内存的方式</p><ul><li>垃圾收集机制,即程序运行时,会不断地寻找不再使用的内存</li><li>程序员必须显示地分配和释放内存</li></ul><p>rust 则采用<strong>所有权系统</strong>来管理内存,包含一组编译器在编译时检查的规则,因为是编译时检查,所以所有权特性不会影响运行时速度</p><h2 id="stack-vs-heap"><a class="markdownIt-Anchor" href="#stack-vs-heap"></a> stack VS heap</h2><p>rust 这样的系统级编程语言,受到 stack 和 heap 的影响非常大</p><p>stack 和 heap 都是代码运行时可用的内存,但是结构不同</p><h3 id="存储数据"><a class="markdownIt-Anchor" href="#存储数据"></a> 存储数据</h3><p>stack 执行 LIFO 原则,即先进后出</p><p>所有存储在 stack 上的数据必须拥有已知的固定的大小</p><p>而编译时大小未知的数据或运行时大小可能发生变化的数据必须存放在 heap 上</p><p>heap 的内存组织性较差</p><ul><li>当把数据放入 heap 时,会请求一定数量的空间</li><li>操作系统在 heap 里找到一块足够大的空间,并标记为在用,返回一个指针,即该空间的地址</li><li>该过程称作在 heap 上进行分配</li></ul><p>把值压在 stack 上不叫分配,但是可以把指针存放在 stack 上</p><p>把数据压到 stack 上要比在 heap 上分配快得多,因为操作系统不需要寻找用来存储新数据的空间,只要往 stack 的顶端压入数据即可</p><p>在 heap 上分配空间需要做更多的工作,需要找到足够大的空间,并且要做好记录</p><h3 id="访问数据"><a class="markdownIt-Anchor" href="#访问数据"></a> 访问数据</h3><p>访问 heap 上的数据要比访问 stack 上的数据慢,因为需要通过指针才能找到 heap 中的数据。</p><p>对于现代处理器而言,由于缓存的缘故,如果指令在内存中跳转的次数越少,那么速度就越快</p><p>如果数据存放的距离比较近,则处理器处理速度更快(stack),反之更慢</p><p>在 heap 上分配大量空间也会消耗事件</p><h3 id="函数调用"><a class="markdownIt-Anchor" href="#函数调用"></a> 函数调用</h3><p>当代码调用函数时,值被传入到函数(也包括指向 heap 的指针),函数本地的变量被压到 stack 上,函数结束时,这些值也会从 stack 上弹出</p><h2 id="所有权存在的原因"><a class="markdownIt-Anchor" href="#所有权存在的原因"></a> 所有权存在的原因</h2><p>所有权要解决的问题:</p><ul><li>跟踪代码的哪些部分正在使用 heap 的哪些数据</li><li>最小化 heap 上的重复数据量</li><li>清理 heap 上未使用的数据以避免空间不足</li></ul><p>管理 heap 数据是所有权存在的原因</p><h2 id="所有权规则"><a class="markdownIt-Anchor" href="#所有权规则"></a> 所有权规则</h2><p>每个值都有一个变量,这个变量是该值的所有者</p><p>每个值同时只能有一个所有者</p><p>当所有者超出作用域(scope)时,该值将被删除</p><h3 id="以-string-类型解释所有权规则"><a class="markdownIt-Anchor" href="#以-string-类型解释所有权规则"></a> 以 String 类型解释所有权规则</h3><p>String 类型的字符串内容是可变的,而字符串字面值是不可变的。因为 String 是在 heap 上分配内存,而字符串字面值是在 stack 上压入字符串</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="comment">// 声明 string 类型的变量</span></span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">s</span> = <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"hello"</span>);</span><br><span class="line"> s.<span class="title function_ invoke__">push_str</span>(<span class="string">" world!"</span>);</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"{}"</span>, s);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>当用完 String 之后,需要使用某种方式将内存返还给操作系统</p><ul><li>在拥有 GC 的语言中,GC 会跟踪并清理不再使用的内存</li><li>没有 GC,就需要识别何时不再使用内存;</li><li><ul><li>如果忘了,就浪费内存</li></ul></li><li><ul><li>如果提前做了,变量就会非法</li></ul></li><li><ul><li>如果做了两次,也是 bug,一次分配对应一次释放,要求每次分配对应一次释放</li></ul></li></ul><p>当超出作用域时,系统会执行 <code>drop()</code> 函数,将变量 s 所指向的内存释放</p><h3 id="变量和数据交互的方式移动move"><a class="markdownIt-Anchor" href="#变量和数据交互的方式移动move"></a> 变量和数据交互的方式:移动(Move)</h3><p>在下面的这种情况下,x 和 y 所代表的两个 6 都被压入 stack 中</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> <span class="variable">x</span> = <span class="number">6</span>;</span><br><span class="line"><span class="keyword">let</span> <span class="variable">y</span> = x;</span><br></pre></td></tr></table></figure><p>而在下面的这种情况中,针对 String 类型的变量,执行 <code>s2 = s</code> 之后,s 便将字符串的所有权交给了 s2,而 s 不再拥有值</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">s</span> = <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"hello world!"</span>);</span><br><span class="line"><span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">s2</span> = s;</span><br></pre></td></tr></table></figure><p>一个 String 由 3 部分组成:一个指向存放字符串内容的内存指针,一个长度,一个容量。这些内容存放在 stack 上,而字符串则存放在 heap 上</p><p>当执行 <code>s2 = s</code>,在 stack 会赋值一份 String 的数据(指针、长度、容量),但是并不会赋值指针所指向的 heap 上的数据,也就是两个指针指向同一个 heap 内存中的位置</p><p>当变量离开作用域时,rust 会自动调用 <code>drop()</code> 函数,将变量使用的 heap 自动释放,当 s 和 s2 都离开作用域时,rust 会释放两者的内存,也就是释放相同的内存,从而造成“二次释放 bug”</p><p>为了保证内存安全:</p><ul><li>rust 没有复制被分配的内存</li><li>在执行 <code>s = s2</code> 之后,rust 是让 s 失效,所以当 s 离开作用域时,rust 不会释放任何东西</li></ul><p>rust 不会自动创建数据的深拷贝</p><p>如果想要深度拷贝 heap 上面的 String 数据,而不仅仅是拷贝 stack 上的数据,可以使用 clone 方法,这种方法比较消耗资源</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">s</span> = <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"hello world!"</span>);</span><br><span class="line"><span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">s2</span> = s.<span class="title function_ invoke__">clone</span>();</span><br></pre></td></tr></table></figure><p>在 stack 上的数据复制叫 copy,比如整数类型的移动,就是在 stack 上进行复制。如果一个类型实现了 copy 这个特性(trait),那么旧的变量在赋值后仍然可用;但是,如果一个类型或者该类型的一部分实现了 drop 这个特性(trait),那么 rust 不允许让它再去实现 copy 了</p><p>一些拥有 copy trait 的类型:</p><ul><li>任何简单标量的组合类型都可以是 copy 的,如:u32, bool, char, f64, tuple(标量1,标量2…)</li><li>任何需要分配内存或者资源的都不是 copy 得到</li></ul><h2 id="所有权与函数"><a class="markdownIt-Anchor" href="#所有权与函数"></a> 所有权与函数</h2><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">s1</span> = <span class="title function_ invoke__">get_ownership</span>(); <span class="comment">// 获得 “some” 的所有权</span></span><br><span class="line"> <span class="title function_ invoke__">take_ownership</span>(s1); <span class="comment">// 所有权交给了 s,s1则失效</span></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">s2</span> = <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"hello_world"</span>);</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">s3</span> = <span class="title function_ invoke__">take_and_give_back</span>(s2); <span class="comment">// s2 转移到了 s3 身上</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">take_ownership</span>(s:Srting) {</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"s:{}"</span>, s);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">get_ownership</span>() <span class="punctuation">-></span> <span class="type">String</span> {</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">some</span> = <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"some"</span>);</span><br><span class="line"> some;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">take_and_give_back</span>(a_string: <span class="type">String</span>) <span class="punctuation">-></span> <span class="type">String</span> {</span><br><span class="line"> a_string; <span class="comment">// 返回值也会发生所有权的转移</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>一个变量的所有权总是遵循同样的模式:</p><ul><li>把一个值赋给其他变量时就会发生移动</li><li>当一个包含 heap 数据的变量离开作用域时,它的值就会被 drop 函数清理掉,除非数据的所有权移动到另一个变量上了</li></ul><h2 id="引用与借用"><a class="markdownIt-Anchor" href="#引用与借用"></a> 引用与借用</h2><p>引用本质上是一个指针,指向这个变量在 stack 中的位置</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">s</span> = <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"hello"</span>);</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">len</span> = <span class="title function_ invoke__">calc_length</span>(&s); <span class="comment">// 引用到 s,但是并不用 s</span></span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"the length of s({}) is {}"</span>, s, len);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 把引用作为函数参数这个行为叫做 “借用”</span></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">calc_length</span>(s: &<span class="type">String</span>) <span class="punctuation">-></span> <span class="type">usize</span> {</span><br><span class="line"> s.<span class="title function_ invoke__">len</span>()</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="可变引用-不可变引用"><a class="markdownIt-Anchor" href="#可变引用-不可变引用"></a> 可变引用、不可变引用</h3><p>不可以修改借用的东西,默认也是不可变的</p><p>如果需要可变,需要加上 <code>mut</code></p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">s</span> = <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"hello"</span>);</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">len</span> = <span class="title function_ invoke__">calc_length</span>(&<span class="keyword">mut</span> s); <span class="comment">// 引用到 s,但是并不用 s</span></span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"the length of s({}) is {}"</span>, s, len);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 把引用作为函数参数这个行为叫做 “借用”</span></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">calc_length</span>(s: &<span class="keyword">mut</span> <span class="type">String</span>) <span class="punctuation">-></span> <span class="type">usize</span> {</span><br><span class="line"> s.<span class="title function_ invoke__">len</span>()</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><strong>可变引用</strong>有一个重要的限制:在特定作用域内,对某一块数据,<strong>只能有一个可变的引用</strong>。好处是在编译时可以防止数据竞争</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> <span class="variable">s1</span> = &<span class="keyword">mut</span> s;</span><br><span class="line"><span class="keyword">let</span> <span class="variable">s2</span> = &<span class="keyword">mut</span> s; <span class="comment">// 会报错</span></span><br></pre></td></tr></table></figure><p>数据竞争的几种行为:</p><ul><li>两个或多个指针同时访问同一个数据;</li><li>至少有一个指针用于写入数据;</li><li>没有使用任何机制来同步对数据的访问;</li></ul><p>可以通过<strong>创建新的作用域</strong>,来允许非同时的创建多个可变引用</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">s1</span> = &<span class="keyword">mut</span> s;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">let</span> <span class="variable">s2</span> = &<span class="keyword">mut</span> s; <span class="comment">// 不会报错</span></span><br></pre></td></tr></table></figure><p>另外一个限制:<strong>不可以同时拥有一个可变引用和一个不可变引用</strong>。因为可变应用修改了引用内容之后,不可变引用就失效了。但是多个不可变引用是可以同时存在的</p><h3 id="悬空引用"><a class="markdownIt-Anchor" href="#悬空引用"></a> 悬空引用</h3><p>Dangling References</p><p>即一个指针引用了内存中的某个地址,而这块内存可能已经释放并分配给其他人使用了</p><p>在 rust 里,编译器可以检查代码从而保证引用永远都不是悬空引用</p><h3 id="引用的规则"><a class="markdownIt-Anchor" href="#引用的规则"></a> 引用的规则</h3><p>在任何给定的时刻,只能满足下列条件之一:</p><ol><li>一个可变的引用</li><li>人以数量不可变的引用</li></ol><p>引用必须一直有效</p><h2 id="切片slice"><a class="markdownIt-Anchor" href="#切片slice"></a> 切片(slice)</h2><p>rust 中的另外一种不持有所有权的数据类型</p><p>指向字符串中一部分内容的引用</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">s</span> = <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"hello world"</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">hello</span> = &s[<span class="number">0</span>..<span class="number">5</span>]; <span class="comment">// 不包括右边界</span></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">hello2</span> = &s[..<span class="number">5</span>]; <span class="comment">// 不包括右边界</span></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">world</span> = &s[<span class="number">5</span>..<span class="number">11</span>];</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">world2</span> = &s[<span class="number">5</span>..];</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">whole</span> = &s[..];</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><img data-src="slice.png" alt="切片内存" /></p><p>字符串切片的类型 <code>&str</code>,函数返回值就用这个</p><p>字符串字面值的就是个切片</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> <span class="variable">s</span>:&<span class="type">str</span> = <span class="string">"hello world"</span>;</span><br></pre></td></tr></table></figure><p>将字符串切片作为参数传递,从而兼容字符串字面值和 String 类型的参数</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">fn</span> <span class="title function_">first_world</span>(s: &<span class="type">String</span>) <span class="punctuation">-></span>&<span class="type">str</span> {}</span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">first_world</span>(s: &<span class="type">str</span>) <span class="punctuation">-></span>&<span class="type">str</span> {}</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> <span class="variable">s1</span> = <span class="type">String</span>:<span class="title function_ invoke__">from</span>(<span class="string">"sss"</span>);</span><br><span class="line"><span class="title function_ invoke__">first_world</span>(&s[..]);</span><br></pre></td></tr></table></figure><p>定义函数时使用字符串切片来代替字符串引用会使我们的 API 更加通用,且不会损失任何功能</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">s</span> = <span class="type">String</span>::<span class="title function_ invoke__">from</span>(<span class="string">"hello world"</span>);</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">s2</span> = <span class="string">"hello world"</span>;</span><br><span class="line"> </span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"the first word of s is: {}"</span>, <span class="title function_ invoke__">first_word</span>(&s[..]));</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"the first word of s2 is: {}"</span>, <span class="title function_ invoke__">first_word</span>(s2));</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">first_word</span>(s: &<span class="type">str</span>) <span class="punctuation">-></span> &<span class="type">str</span> {</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">bytes</span> = s.<span class="title function_ invoke__">as_bytes</span>();</span><br><span class="line"> <span class="title function_ invoke__">for</span> (idx, &item) <span class="keyword">in</span> bytes.<span class="title function_ invoke__">iter</span>().<span class="title function_ invoke__">enumerate</span>() {</span><br><span class="line"> <span class="keyword">if</span> item == <span class="string">b' '</span> {</span><br><span class="line"> <span class="keyword">return</span> &s[..idx];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> &s[..]</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>其他类型的切片</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> <span class="variable">a</span> = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>];</span><br><span class="line"><span class="keyword">let</span> <span class="variable">b</span>:&[<span class="type">i32</span>] = &a[<span class="number">1</span>..<span class="number">3</span>]; <span class="comment">// b 的类型是 &[i32]</span></span><br></pre></td></tr></table></figure><hr /><h2 id="参考"><a class="markdownIt-Anchor" href="#参考"></a> 参考</h2><ol><li><a href="https://www.youtube.com/watch?v=e3-2uxHhbzs&list=PL3azK8C0kje1DUJbaOqce19j3R_-tIc4_&index=1&t=140s">https://www.youtube.com/watch?v=e3-2uxHhbzs&list=PL3azK8C0kje1DUJbaOqce19j3R_-tIc4_&index=1&t=140s</a></li><li>《rust权威指南(The Rust Programming Language)》</li></ol>]]></content>
<summary type="html"><p>rust 教程 04: 所有权</p></summary>
<category term="rust" scheme="http://www.kimroniny.top/categories/rust/"/>
<category term="rust" scheme="http://www.kimroniny.top/tags/rust/"/>
</entry>
<entry>
<title>serverless基础</title>
<link href="http://www.kimroniny.top/2022/10/21/serverless%E5%9F%BA%E7%A1%80/"/>
<id>http://www.kimroniny.top/2022/10/21/serverless%E5%9F%BA%E7%A1%80/</id>
<published>2022-10-21T06:08:10.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>serverless 的基础内容</p><span id="more"></span><h2 id="概念"><a class="markdownIt-Anchor" href="#概念"></a> 概念</h2><p>Serverless computing 无服务器运算,又称为函数即服务(Function as a service,即 FaaS)</p><p>我们不再需要关心服务(如 mysql、redis等)的申请机器、资源部署、资源碎片、弹性扩缩容问题,不再需要日夜值守关心各个依赖组件各项指标出现的问题,我们只需要聚焦在自己的上层业务逻辑上进行实现和优化,并且再也不会有闲置资源或者碎片资源问题 (按需使用),这个就是 Serverless 想要构建的架构体系。</p><h2 id="架构演进"><a class="markdownIt-Anchor" href="#架构演进"></a> 架构演进</h2><p>从整个演进过程来看,一直都在朝着资源切分粒度越来越细(<strong>物理机 -> 操作系统 -> 进程 -> function</strong>),资源利用率越来越高,运维工作越来越少,开发更聚焦业务方向。</p><p>物理机时代</p><p>虚拟化时代(重量级 VM),将物理机切分成一个个 VM 实例</p><p>云时代,云服务提供商,还是采用重量级 VM</p><p>虚拟化时代(轻量级容器 docker),devOps 开始火热,强制运维转开发,但是开发还是要关心运维</p><p>Serverless,去运维,开发人员只关注业务逻辑开发</p><h2 id="如何影响微服务"><a class="markdownIt-Anchor" href="#如何影响微服务"></a> 如何影响微服务</h2><p>serverless 是技术架构,微服务是业务架构,经济基础决定上层建筑,底层技术架构形式影响上层业务</p><p>以前的微服务以应用形式来组织,很多服务可能用到相同的功能,但是这些功能并没有达到可以分解为一个微服务的程度,此时,各个服务都会开发这一功能,从而导致代码重复。虽然可以使用共享库来解决,但是多语言环境下不一定行得通</p><p>而 serverless 架构中以 function 为最小粒度组织,业务分隔粒度可以无限小,任何一个模块功能甚至方法都可以独立存在,不需要通过共享库或者共享组件来复用。所以,在 Serverless 架构中,微服务组件的相互隔离和模块松耦合可以做的更好,应用甚至可以以独立函数的形式存在</p><h2 id="和云原生的关系"><a class="markdownIt-Anchor" href="#和云原生的关系"></a> 和云原生的关系</h2><p>serverless 就是为云而生的东西,天生具有云的基因(免运维弹性伸缩按量计费)</p><p>只需要聚焦业务逻辑不需要去关心和管理资源问题,是对容器技术的封装,代表了云原生的高级阶段</p><h2 id="serverless-要解决的问题"><a class="markdownIt-Anchor" href="#serverless-要解决的问题"></a> serverless 要解决的问题</h2><ol><li>机器资源分布不均</li></ol><p>一个大型系统包括多种业务,通过拆分集群来进行业务隔离,不同集群由于不同的特性,会出现差距较大的资源利用率</p><ol start="2"><li>错峰问题</li></ol><p>如果就为了一天 1 个小时的高峰流量来准备全天的机器,那剩下来的那 23 小时也是一种资源的浪费</p><ol start="3"><li>碎片化问题</li></ol><p>微服务之间的数据交互主要是 RPC 和 MQ,常见的 RPC 框架本身就有比较完善的探活和负载均衡机制能够保证流量在不同机器的的均衡性,而 MQ 受限于顺序消费、失败重发、消息分区等特性没有办法很好的保证消费端负载均衡,比如我们常用的 RocketMQ 默认使用了一种分页的算法,即在客户端将消费者和分区分别按照字典序排好,再按照平均分配的原则每个消费者分 “一页” 的分区,所以这里就会引申出碎片的问题,当一个集群中消费的 Metaq 消息都是小分区的消息,所有的消息都会被流入集群中的前几个机器中,造成集群整体流量不均,带来集群资源碎片。</p><ol start="4"><li>资源问题</li></ol><p>对于新接入的用户和业务,我们常见的做法是评估峰值业务量然后为其开启新集群预先分配一批机器,这里就有两个问题,一个是对于资源的预先评估是否能够准确而不造成浪费,另一个是成本结算方式,如果使用机器数来给用户或者业务方结算成本,对于有明显波峰波谷的使用者来说也是一种很大的成本资源浪费。</p><ol start="5"><li>运维问题</li></ol><p>在每次大促或者压测之前都需要提前扩缩容准备资源、修改集群配置,随着各种大促小促和压测次数越来越密集,这种运维开销成本也变得越来越大。</p><hr /><h2 id="参考"><a class="markdownIt-Anchor" href="#参考"></a> 参考</h2><ol><li><a href="https://my.oschina.net/u/5783135/blog/5584238">Serverless 架构演进与实践</a></li></ol>]]></content>
<summary type="html"><p>serverless 的基础内容</p></summary>
<category term="serverless" scheme="http://www.kimroniny.top/categories/serverless/"/>
<category term="serverless" scheme="http://www.kimroniny.top/tags/serverless/"/>
</entry>
<entry>
<title>rust教程-03</title>
<link href="http://www.kimroniny.top/2022/10/20/rust%E6%95%99%E7%A8%8B-03/"/>
<id>http://www.kimroniny.top/2022/10/20/rust%E6%95%99%E7%A8%8B-03/</id>
<published>2022-10-20T11:28:22.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>rust 教程 03: 基本内容</p><span id="more"></span><h2 id="变量-常量-隐藏"><a class="markdownIt-Anchor" href="#变量-常量-隐藏"></a> 变量、常量、隐藏</h2><h3 id="变量"><a class="markdownIt-Anchor" href="#变量"></a> 变量</h3><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> <span class="variable">x</span> = <span class="number">5</span>; <span class="comment">// 不可变变量</span></span><br><span class="line"><span class="keyword">let</span> <span class="variable">mul</span> x = <span class="number">3</span>; <span class="comment">// 可变变量,通过 mut 修饰符</span></span><br></pre></td></tr></table></figure><h3 id="常量"><a class="markdownIt-Anchor" href="#常量"></a> 常量</h3><p>常量 constant,绑定值以后也是不可变的,但是与不可变变量有很多区别</p><ol><li>不可以使用 mut 修饰符,常量永远不可变</li><li>声明常量使用 const,且必须标注类型</li><li>可以在任何作用域内声明,包括全局作用域</li><li>只可以绑定到常量表达式,无法绑定到函数的调用结果或者运行时才能计算出的值<br />命名规范:使用全大写字母,用下划线分开单词</li></ol><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> MAX_POINTS: <span class="type">u32</span> = <span class="number">100</span>;</span><br></pre></td></tr></table></figure><h3 id="隐藏"><a class="markdownIt-Anchor" href="#隐藏"></a> 隐藏</h3><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> <span class="variable">y</span> = <span class="number">1</span>;</span><br><span class="line"><span class="comment">// y = y + 1; // error: 不可变变量</span></span><br><span class="line"><span class="keyword">let</span> <span class="variable">y</span> = y + <span class="number">1</span>; <span class="comment">// ok: 隐藏了上一个 y</span></span><br><span class="line"><span class="keyword">let</span> <span class="variable">y</span> = <span class="string">"hello"</span>; <span class="comment">// ok: 可以改变 y 的类型</span></span><br></pre></td></tr></table></figure><h2 id="强类型语言"><a class="markdownIt-Anchor" href="#强类型语言"></a> 强类型语言</h2><p>rust 是静态编译语言,在编译时必须直到所有变量的类型,即:</p><ul><li>基于使用的值,编译器可以推断出它的具体类型</li><li>如果类型比较多,必须添加类型标注,否则编译报错</li></ul><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 变量 x 必须指明类型 u32,因为 parse() 的结果产生的类型可能有很多,比如 i32,i64,u64 等等</span></span><br><span class="line"><span class="keyword">let</span> <span class="variable">x</span>: <span class="type">u32</span> = <span class="string">"43"</span>.<span class="title function_ invoke__">parse</span>().<span class="title function_ invoke__">expect</span>(<span class="string">"pls input a number"</span>); </span><br></pre></td></tr></table></figure><h2 id="标量类型"><a class="markdownIt-Anchor" href="#标量类型"></a> 标量类型</h2><p>一个标量类型代表一个单个的值</p><p>四个标量类型:整数、浮点、布尔、字符</p><h3 id="整数类型"><a class="markdownIt-Anchor" href="#整数类型"></a> 整数类型</h3><ul><li>十进制:97_88 可以加下划线</li><li>十六进制:0xff 可以加下划线</li><li>八进制:0o99 可以加下划线</li><li>二进制:0b01_0101 可以加下划线</li><li>字节(u8):b’A’</li></ul><p>整数溢出:</p><ul><li>debug模式下,会 panic</li><li>release 模式下,会发生“环绕”操作,不会 panic</li></ul><h3 id="浮点类型"><a class="markdownIt-Anchor" href="#浮点类型"></a> 浮点类型</h3><ul><li>f32,32位,单精度</li><li>f64,64位,双精度,默认类型,精度更高,和 f32 的速度在现代 CPU 上差不多</li></ul><h3 id="布尔类型"><a class="markdownIt-Anchor" href="#布尔类型"></a> 布尔类型</h3><p>bool</p><ul><li>true</li><li>false</li></ul><h3 id="字符类型"><a class="markdownIt-Anchor" href="#字符类型"></a> 字符类型</h3><p>char</p><p>单引号</p><p>占用 4 个字节</p><p>Unicode 标量值,可以表示比 ASCII 多得多的字符内容</p><ul><li>U+0000 到 U+D7FF</li><li>U+E000 到 U+10FFFF</li></ul><h2 id="复合类型"><a class="markdownIt-Anchor" href="#复合类型"></a> 复合类型</h2><p>复合类型:可以将多个值放在一个类型里</p><p>两种基础的复合类型:元组(Tuple)、数组</p><h3 id="tuple"><a class="markdownIt-Anchor" href="#tuple"></a> Tuple</h3><p>可以将多个类型的值放在一个类型里,每个位置对应一个类型</p><p>长度固定,一旦声明无法改变</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> <span class="variable">tup</span>:(<span class="type">i32</span>, <span class="type">f64</span>, <span class="type">u8</span>) = (<span class="number">400</span>, <span class="number">4.6</span>, <span class="number">1</span>); </span><br><span class="line"><span class="keyword">let</span> (x, y, z) = tup;</span><br><span class="line"><span class="built_in">println!</span>(<span class="string">"{}, {}, {}"</span>, tup.<span class="number">0</span>, tup.<span class="number">1</span>, tup.<span class="number">2</span>); <span class="comment">// 通过 .index 的方式来取值</span></span><br></pre></td></tr></table></figure><h3 id="数组"><a class="markdownIt-Anchor" href="#数组"></a> 数组</h3><p>如果想要保存数据在栈而不是堆上,或者保证有固定数量的元素,就可以使用数组</p><p>数组没有 vector 灵活,vector 由标准库提供</p><p>优先使用 vector</p><p>访问越界的话,在编译期间不会报错,但是在运行时会 panic,rust 不允许访问越界地址的内存</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> <span class="variable">a</span> = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>];</span><br><span class="line"><span class="keyword">let</span> <span class="variable">a</span>: [<span class="type">i32</span>: <span class="number">5</span>] = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>]; <span class="comment">// [类型:长度]</span></span><br><span class="line"><span class="keyword">let</span> <span class="variable">a</span> = [<span class="number">3</span>; <span class="number">5</span>]; <span class="comment">// 等同于 let a = [3,3,3,3,3],即 a = [初始值;长度]</span></span><br></pre></td></tr></table></figure><h2 id="函数"><a class="markdownIt-Anchor" href="#函数"></a> 函数</h2><p>针对函数和变量名,使用 snake case 命名规范,所有字母小写</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="title function_ invoke__">add</span>(<span class="number">34</span>,<span class="number">5</span>); <span class="comment">// argument</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// parameter, 必须声明每个参数的类型</span></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">add</span>(x: <span class="type">i32</span>, y: <span class="type">i32</span>) <span class="punctuation">-></span> <span class="type">i32</span>{ <span class="comment">// 只有返回值的类型,不可以为返回值命名</span></span><br><span class="line"> x + y <span class="comment">// 最后一个表达式即为返回值,也可以使用 return 提前返回</span></span><br><span class="line"> <span class="comment">// x + y; // 不可以加分号,如果加了分号,就是语句,语句的返回值是空的 tuple,即 () </span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="控制流-条件表达式"><a class="markdownIt-Anchor" href="#控制流-条件表达式"></a> 控制流: 条件表达式</h2><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">x</span> = <span class="number">3</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> x % <span class="number">10</span> == <span class="number">0</span> {</span><br><span class="line"></span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> x % <span class="number">3</span> == <span class="number">0</span> {</span><br><span class="line"></span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> x % <span class="number">7</span> == <span class="number">0</span> {</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">y</span> = <span class="keyword">if</span> x % <span class="number">10</span> == <span class="number">0</span> { <span class="number">5</span> } <span class="keyword">else</span> { <span class="number">6</span> }; <span class="comment">// 返回值类型必须是统一的,即编译期间能够确定类型</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="控制流-循环"><a class="markdownIt-Anchor" href="#控制流-循环"></a> 控制流: 循环</h2><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"></span><br><span class="line"> <span class="comment">// loop 循环</span></span><br><span class="line"> <span class="keyword">loop</span> {</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"loop..."</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// loop 循环返回一个结果</span></span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">counter</span> = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">let</span> <span class="variable">result</span> = <span class="keyword">loop</span> {</span><br><span class="line"> counter += <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span> counter == <span class="number">10</span> {</span><br><span class="line"> <span class="keyword">break</span> counter; <span class="comment">// 通过 break 返回当前 loop 的值</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// while 循环</span></span><br><span class="line"> <span class="keyword">while</span> counter != <span class="number">100</span> {</span><br><span class="line"> counter += <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// for 循环</span></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">a</span> = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>];</span><br><span class="line"> <span class="keyword">for</span> <span class="variable">element</span> <span class="keyword">in</span> a.<span class="title function_ invoke__">iter</span>() {</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"element is {}"</span>, element);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// for range</span></span><br><span class="line"> <span class="keyword">for</span> <span class="variable">element</span> <span class="keyword">in</span> (<span class="number">1</span>..<span class="number">4</span>).<span class="title function_ invoke__">rev</span>() { <span class="comment">// (1..4) 只有 1,2,3 不包括 4,rev 就是反转一下</span></span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"element is {}"</span>, element);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr /><h2 id="参考"><a class="markdownIt-Anchor" href="#参考"></a> 参考</h2><ol><li><a href="https://www.youtube.com/watch?v=e3-2uxHhbzs&list=PL3azK8C0kje1DUJbaOqce19j3R_-tIc4_&index=1&t=140s">https://www.youtube.com/watch?v=e3-2uxHhbzs&list=PL3azK8C0kje1DUJbaOqce19j3R_-tIc4_&index=1&t=140s</a></li><li>《rust权威指南(The Rust Programming Language)》</li></ol>]]></content>
<summary type="html"><p>rust 教程 03: 基本内容</p></summary>
<category term="rust" scheme="http://www.kimroniny.top/categories/rust/"/>
<category term="rust" scheme="http://www.kimroniny.top/tags/rust/"/>
</entry>
<entry>
<title>rust教程-02</title>
<link href="http://www.kimroniny.top/2022/10/18/rust%E6%95%99%E7%A8%8B-02/"/>
<id>http://www.kimroniny.top/2022/10/18/rust%E6%95%99%E7%A8%8B-02/</id>
<published>2022-10-18T13:44:06.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>rust 教程 02: 例子</p><span id="more"></span><p>一个简单的猜数小游戏。</p><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 导入包的方式</span></span><br><span class="line"><span class="keyword">use</span> rand::Rng; <span class="comment">// 为什么导入 rng,但是下面没有用 rng,而是直接用 rand::thread_rng().gen_range();</span></span><br><span class="line"><span class="keyword">use</span> std::{cmp::Ordering, io};</span><br><span class="line"></span><br><span class="line"><span class="keyword">fn</span> <span class="title function_">main</span>() {</span><br><span class="line"> <span class="comment">// let x = String::new(); 不加 mut 修饰词,则默认为 immut</span></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">secret_number</span> = rand::<span class="title function_ invoke__">thread_rng</span>().<span class="title function_ invoke__">gen_range</span>(<span class="number">1</span>, <span class="number">101</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">loop</span> {</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"please input a number:"</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut </span><span class="variable">guess</span> = <span class="type">String</span>::<span class="title function_ invoke__">new</span>();</span><br><span class="line"> io::<span class="title function_ invoke__">stdin</span>().<span class="title function_ invoke__">read_line</span>(&<span class="keyword">mut</span> guess).<span class="title function_ invoke__">expect</span>(<span class="string">"input error!"</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// let guess: u32 = guess.trim().parse().expect("pls input an interger...");</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> <span class="variable">guess</span>: <span class="type">u32</span> = <span class="keyword">match</span> guess.<span class="title function_ invoke__">trim</span>().<span class="title function_ invoke__">parse</span>() {</span><br><span class="line"> <span class="title function_ invoke__">Ok</span>(num) => num,</span><br><span class="line"> <span class="title function_ invoke__">Err</span>(_) => <span class="keyword">continue</span>,</span><br><span class="line"> };</span><br><span class="line"></span><br><span class="line"> <span class="keyword">match</span> guess.<span class="title function_ invoke__">cmp</span>(&secret_number) {</span><br><span class="line"> Ordering::Equal => {</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"win!!!"</span>);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> Ordering::Less => {</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"less~"</span>);</span><br><span class="line"> }</span><br><span class="line"> Ordering::Greater => {</span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"greater~"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><hr /><h2 id="参考"><a class="markdownIt-Anchor" href="#参考"></a> 参考</h2><ol><li><a href="https://www.youtube.com/watch?v=e3-2uxHhbzs&list=PL3azK8C0kje1DUJbaOqce19j3R_-tIc4_&index=1&t=140s">https://www.youtube.com/watch?v=e3-2uxHhbzs&list=PL3azK8C0kje1DUJbaOqce19j3R_-tIc4_&index=1&t=140s</a></li><li>《rust权威指南(The Rust Programming Language)》</li></ol>]]></content>
<summary type="html"><p>rust 教程 02: 例子</p></summary>
<category term="rust" scheme="http://www.kimroniny.top/categories/rust/"/>
<category term="rust" scheme="http://www.kimroniny.top/tags/rust/"/>
</entry>
<entry>
<title>wsl 数据迁移</title>
<link href="http://www.kimroniny.top/2022/10/18/wsl-%E6%95%B0%E6%8D%AE%E8%BF%81%E7%A7%BB/"/>
<id>http://www.kimroniny.top/2022/10/18/wsl-%E6%95%B0%E6%8D%AE%E8%BF%81%E7%A7%BB/</id>
<published>2022-10-17T17:27:01.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>wsl 数据迁移到其他硬盘</p><span id="more"></span><p>wsl 的默认目录 <code>C:\Users\kimroniny\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc</code></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看所有的 wsl</span></span><br><span class="line">wsl -l -v </span><br><span class="line"><span class="comment"># 导出想要迁移的 wsl 到 tar</span></span><br><span class="line">wsl --<span class="built_in">export</span> Ubuntu-18.04 D:\wsl\Ubuntu.tar</span><br><span class="line"><span class="comment"># 注销想要迁移的 wsl, 此时原目录下的数据 ./LocalState 就消失了</span></span><br><span class="line">wsl --unregister Ubuntu-18.04</span><br><span class="line"><span class="comment"># 导入到指定目录</span></span><br><span class="line">wsl --import Ubuntu-18.04 D:\wsl\wsl2 D:\wsl\Ubuntu.tar --version 2</span><br><span class="line"><span class="comment"># 设置默认登录用户为指定用户</span></span><br><span class="line">ubuntu1804 config --default-user kimroniny</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>wsl 数据迁移到其他硬盘</p></summary>
<category term="wsl" scheme="http://www.kimroniny.top/categories/wsl/"/>
<category term="wsl" scheme="http://www.kimroniny.top/tags/wsl/"/>
</entry>
<entry>
<title>ssh 登录到 wsl</title>
<link href="http://www.kimroniny.top/2022/10/18/ssh-%E7%99%BB%E5%BD%95%E5%88%B0-wsl/"/>
<id>http://www.kimroniny.top/2022/10/18/ssh-%E7%99%BB%E5%BD%95%E5%88%B0-wsl/</id>
<published>2022-10-17T17:18:05.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>局域网内主机登录到其他主机的 wsl</p><span id="more"></span><h2 id="wsl-到-windows-的端口映射"><a class="markdownIt-Anchor" href="#wsl-到-windows-的端口映射"></a> wsl 到 windows 的端口映射</h2><p>在 wsl 中通过 ifconfig 查看 ip,一定要使用该 ip,不要使用 windows 网络设置中 vEthernet switch 或者 vEthernet wsl 的 ip 地址。</p><p>假设该 ip 为 192.168.186.222</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># listenport: 对外开放的端口</span></span><br><span class="line"><span class="comment"># connectaddress: wsl 的内部 ip</span></span><br><span class="line"><span class="comment"># connectport: wsl 的 ssh 端口</span></span><br><span class="line">netsh interface portproxy add v4tov4 listenport=50022 connectaddress=192.168.186.222 connectport=22 listenaddress=* protocol=tcp </span><br><span class="line"></span><br><span class="line"><span class="comment"># 删除端口转发</span></span><br><span class="line">netsh interface portproxy delete v4tov4 listenport=80 protocol=tcp</span><br></pre></td></tr></table></figure><p>在 windows 的防火墙高级设置中,在入规则中开放 50022 端口。</p><h2 id="配置-ssh"><a class="markdownIt-Anchor" href="#配置-ssh"></a> 配置 ssh</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 重新安装 ssh</span></span><br><span class="line">apt uninstall openssh-server</span><br><span class="line">apt update <span class="comment"># 有的 ubuntu 内核已经很旧了,会导致 install 时出现 url 失效的问题</span></span><br><span class="line">apt install openssh-server</span><br><span class="line"></span><br><span class="line"><span class="comment"># ssh 的配置文件</span></span><br><span class="line">/etc/ssh/sshd_config</span><br><span class="line"><span class="comment"># 本地用户的 ssh 目录</span></span><br><span class="line"><span class="built_in">chmod</span> 700 -R ~/.ssh </span><br><span class="line"><span class="built_in">chmod</span> 600 ~/.ssh/authorized_keys</span><br><span class="line"><span class="built_in">chown</span> user:user -R ~/.ssh</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>局域网内主机登录到其他主机的 wsl</p></summary>
<category term="wsl" scheme="http://www.kimroniny.top/categories/wsl/"/>
<category term="wsl" scheme="http://www.kimroniny.top/tags/wsl/"/>
<category term="ssh" scheme="http://www.kimroniny.top/tags/ssh/"/>
</entry>
<entry>
<title>rust教程-01</title>
<link href="http://www.kimroniny.top/2022/10/17/rust%E6%95%99%E7%A8%8B-01/"/>
<id>http://www.kimroniny.top/2022/10/17/rust%E6%95%99%E7%A8%8B-01/</id>
<published>2022-10-17T04:56:39.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>rust 教程 01: 环境部署</p><span id="more"></span><h2 id="基础知识"><a class="markdownIt-Anchor" href="#基础知识"></a> 基础知识</h2><p>rust 擅长的领域:</p><ul><li>高性能 web service</li><li>WebAssembly</li><li>命令行工具</li><li>网络编程</li><li>嵌入式设备</li><li>系统编程</li></ul><p>rust 的优点:</p><ul><li>性能(媲美 c/c++)</li><li>安全性(内存)</li><li>无所畏惧的并发</li></ul><h2 id="安装"><a class="markdownIt-Anchor" href="#安装"></a> 安装</h2><p>官网:<a href="https://www.rust-lang.org/">https://www.rust-lang.org/</a></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">rustup update <span class="comment"># 更新</span></span><br><span class="line">rustup self uninstall <span class="comment"># 卸载</span></span><br><span class="line">rustc --version <span class="comment"># 版本</span></span><br></pre></td></tr></table></figure><p>安装的时候可能会出现 openssl 的问题, 此时需要设置</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">export</span> RUSTUP_DIST_SERVER=https://mirrors.ustc.edu.cn/rust-static</span><br><span class="line"><span class="built_in">export</span> RUSTUP_UPDATE_ROOT=https://mirrors.ustc.edu.cn/rust-static/rustup</span><br></pre></td></tr></table></figure><p>开发工具:<code>vscode</code></p><p>插件:<code>rust</code></p><h2 id="基本程序"><a class="markdownIt-Anchor" href="#基本程序"></a> 基本程序</h2><p>后缀名:<code>.rs</code></p><p>文件命名规范:<code>hello_world.rs</code></p><p>编译:<code>rustc main.rs</code>,产生可执行文件</p><p>编译需要服务器安装 <code>gcc</code></p><p>rust 是 ahead-of-time 编译的语言,可以先编译,然后把可执行文件交给别人运行(无需安装 rust)。</p><h2 id="cargo"><a class="markdownIt-Anchor" href="#cargo"></a> cargo</h2><p>cargo 是 rust 的构建系统和包管理工具,即:构建代码、下载依赖的库、构建这些库…</p><p>安装 rust 的时候会安装 cargo。<code>cargo --version</code></p><p>包 packages 在 cargo 中叫做 <code>crate</code></p><p>cargo 生成的 <a href="http://main.rs">main.rs</a> 放在 src/ 目录下, cargo.toml 在项目顶层下,源代码都在 src/ 目录下,顶层目录可以放 readme、许可信息、配置文件、说明文档等与程序源码无关的文件</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">cargo --version</span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建项目 hello_cargo</span></span><br><span class="line"><span class="comment"># 包括文件:</span></span><br><span class="line"><span class="comment"># # cargo.toml 配置文件</span></span><br><span class="line"><span class="comment"># # src/ 源代码</span></span><br><span class="line"><span class="comment"># # .gitignore </span></span><br><span class="line">cargo new hello_cargo</span><br><span class="line"></span><br><span class="line"><span class="comment"># 编译,创建可执行文件</span></span><br><span class="line"><span class="comment"># target/build/hello_cargo.exe</span></span><br><span class="line"><span class="comment"># cargo.lock文件,负责追踪项目依赖的精确版本</span></span><br><span class="line">cargo build</span><br><span class="line"></span><br><span class="line"><span class="comment"># 编译 + 执行</span></span><br><span class="line"><span class="comment"># 如果已经编译过且代码未修改,则直接执行</span></span><br><span class="line">cargo run</span><br><span class="line"></span><br><span class="line"><span class="comment"># 检查代码是否可以通过编译,不产生可执行文件</span></span><br><span class="line"><span class="comment"># 可以连续反复使用</span></span><br><span class="line">cargo check</span><br><span class="line"></span><br><span class="line"><span class="comment"># 为发布构建</span></span><br><span class="line"><span class="comment"># 编译时会进行优化,代码运行的更快,但是编译时间会更长</span></span><br><span class="line"><span class="comment"># target/release</span></span><br><span class="line">cargo build --release</span><br></pre></td></tr></table></figure><blockquote><p>第一次执行的时候, 可能出现缺少 <code>cc</code> 的问题.<br />可以通过 <code>apt install build-essential</code> 解决</p></blockquote><p>cargo 更换国内源,在 <code>~/.cargo/config</code> 文件中填写下面内容,网络上提供了很多国内源,但是好像只有中科大的能用。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">[source.crates-io]</span><br><span class="line">registry = "https://github.com/rust-lang/crates.io-index"</span><br><span class="line"># 指定镜像</span><br><span class="line">replace-with = 'ustc'</span><br><span class="line"></span><br><span class="line"># 中国科学技术大学</span><br><span class="line">[source.ustc]</span><br><span class="line">registry = "git://mirrors.ustc.edu.cn/crates.io-index"</span><br></pre></td></tr></table></figure><hr /><h2 id="参考"><a class="markdownIt-Anchor" href="#参考"></a> 参考</h2><ol><li><a href="https://www.youtube.com/watch?v=e3-2uxHhbzs&list=PL3azK8C0kje1DUJbaOqce19j3R_-tIc4_&index=1&t=140s">https://www.youtube.com/watch?v=e3-2uxHhbzs&list=PL3azK8C0kje1DUJbaOqce19j3R_-tIc4_&index=1&t=140s</a></li><li>《rust权威指南(The Rust Programming Language)》</li></ol>]]></content>
<summary type="html"><p>rust 教程 01: 环境部署</p></summary>
<category term="rust" scheme="http://www.kimroniny.top/categories/rust/"/>
<category term="rust" scheme="http://www.kimroniny.top/tags/rust/"/>
</entry>
<entry>
<title>软件架构模式演进</title>
<link href="http://www.kimroniny.top/2022/10/17/%E8%BD%AF%E4%BB%B6%E6%9E%B6%E6%9E%84%E6%A8%A1%E5%BC%8F%E6%BC%94%E8%BF%9B/"/>
<id>http://www.kimroniny.top/2022/10/17/%E8%BD%AF%E4%BB%B6%E6%9E%B6%E6%9E%84%E6%A8%A1%E5%BC%8F%E6%BC%94%E8%BF%9B/</id>
<published>2022-10-17T02:06:08.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>软件架构模式基本演进过程。</p><span id="more"></span><p><strong>软件的架构模式总的说经历了三个阶段的演进:从单机、集中式到分布式微服务架构。</strong></p><h2 id="单机架构"><a class="markdownIt-Anchor" href="#单机架构"></a> 单机架构</h2><p>通常采用面向过程的设计方法。采用 C/S 架构。</p><h2 id="集中式架构"><a class="markdownIt-Anchor" href="#集中式架构"></a> 集中式架构</h2><p>通常采用面向对象的设计方法。采用三层架构 MVC,系统包括业务接入层、业务逻辑层和数据库层。</p><h2 id="分布式微服务架构"><a class="markdownIt-Anchor" href="#分布式微服务架构"></a> 分布式微服务架构</h2><p>可以实现业务和应用之间的解耦,解决单体应用扩展性差、弹性伸缩能力不足的问题,适合在云环境下部署运营。</p><p><strong>三种设计模式的演进:页面驱动设计,数据驱动设计,领域驱动设计。</strong></p><h2 id="页面驱动设计"><a class="markdownIt-Anchor" href="#页面驱动设计"></a> 页面驱动设计</h2><p>主要集中在客户端开发过程。</p><p>以设计稿为标准进行开发的,每位客户端开发的同学要开展工作都离不开 UI 设计师的设计稿。</p><h2 id="数据驱动设计"><a class="markdownIt-Anchor" href="#数据驱动设计"></a> 数据驱动设计</h2><p>主要集中在服务端开发过程。</p><p>设计数据库表结构是最重要的环节:对业务的理解程度,对可扩展性的考虑程度都直接影响到了我们会“如何设计数据库表结构”;数据库表结构设计是否合理,也直接影响了我们后续开发业务逻辑是否顺利</p><h2 id="领域驱动设计-ddddomain-driven-design"><a class="markdownIt-Anchor" href="#领域驱动设计-ddddomain-driven-design"></a> 领域驱动设计 DDD(Domain Driven Design)</h2><p>核心思想是避免<strong>业务逻辑的复杂性</strong>和<strong>技术实现的复杂性</strong>耦合在一起。</p><p>最大的价值在于梳理业务需求,抽象出一个个“领域”,并形成各个领域之间的交互接口。</p><p>“模型”是 DDD 中的重要概念:模型是对领域的抽象和模拟。</p><p>“建模”是 DDD 中重要的手段:建模时针对特定问题建立该领域的合理模型。</p><p>观点:不以用户为中心。DDD 认为:以用户为中心是表层需求,真正的需求是基于领域的,领域之所以有意义,一定是和人有关系。</p><p><strong>转变编程语言到 golang 的制胜法宝:三刷官方文档</strong></p><ul><li>一刷:从头看到尾,扫清知识盲点和概念;</li><li>二刷:手敲,注释和总结;</li><li>三刷:写注释,不看文档实现功能,遇到问题再和文档比较,加深理解。</li></ul><hr /><p>参考:</p><ol><li><a href="https://xie.infoq.cn/article/70fc253b683d5a7eaac833617">给想转 Go 或者 Go 进阶同学的一些建议</a></li></ol>]]></content>
<summary type="html"><p>软件架构模式基本演进过程。</p></summary>
<category term="architect" scheme="http://www.kimroniny.top/categories/architect/"/>
<category term="software design" scheme="http://www.kimroniny.top/categories/architect/software-design/"/>
<category term="architect" scheme="http://www.kimroniny.top/tags/architect/"/>
<category term="software design" scheme="http://www.kimroniny.top/tags/software-design/"/>
</entry>
<entry>
<title>软件开发模式</title>
<link href="http://www.kimroniny.top/2022/10/15/%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91%E6%A8%A1%E5%BC%8F/"/>
<id>http://www.kimroniny.top/2022/10/15/%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91%E6%A8%A1%E5%BC%8F/</id>
<published>2022-10-15T15:01:20.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>四种软件开发模式。</p><span id="more"></span><h2 id="瀑布开发模式"><a class="markdownIt-Anchor" href="#瀑布开发模式"></a> 瀑布开发模式</h2><p>一种传统的软件开发模式。</p><p>包括五个顺序阶段:需求,设计,实现,测试,维护。</p><p>如果软件项目对稳定要求比较高,则可以选择瀑布开发模式。但是该模式开发事件久,成本高。</p><h2 id="快速应用开发模式"><a class="markdownIt-Anchor" href="#快速应用开发模式"></a> 快速应用开发模式</h2><p>比较精简的软件开发流程,可以低成本生产高质量的软件。需要开发人员快速适应不断变化的市场需求。</p><p>包括四个阶段:需求设计,用户设计,构建,切换。重复用户设计和施工阶段,直到满足用户所有要求。</p><p>适合中小型软件开发项目,需要开发人员具有丰富的开发经验,非常了解用户的核心需求。</p><h2 id="敏捷开发模式"><a class="markdownIt-Anchor" href="#敏捷开发模式"></a> 敏捷开发模式</h2><p>拥有多种不同的形式,包括:Scrum,Crystal,XP 和 FDD 等。</p><p>通过迭代开发,互动沟通等方法来降低软件开发过程中的风险,通过早期发现和修复缺陷来提高开发的效率,比较依赖用户的信息反馈。</p><p>适用于小规模的软件开发公司。</p><h2 id="devops部署模式"><a class="markdownIt-Anchor" href="#devops部署模式"></a> DevOps部署模式</h2><p>增强了软件开发部门之间的协作(开发、测试、运营等)。着重于改进软件的上市时间,降低新版本的故障率,缩短 BUG 修复时间,优先考虑最小的中断以及最大的可靠性等。</p><p>对提高客户满意度,提高产品质量,提高员工的生产力和效率得益等方面非常有用。</p><p><strong>参考:</strong><br />1.<a href="https://blog.csdn.net/qq_19970313/article/details/124783524">https://blog.csdn.net/qq_19970313/article/details/124783524</a></p>]]></content>
<summary type="html"><p>四种软件开发模式。</p></summary>
<category term="architect" scheme="http://www.kimroniny.top/categories/architect/"/>
<category term="software design" scheme="http://www.kimroniny.top/categories/architect/software-design/"/>
<category term="architect" scheme="http://www.kimroniny.top/tags/architect/"/>
<category term="software design" scheme="http://www.kimroniny.top/tags/software-design/"/>
</entry>
<entry>
<title>自我安慰 - 吧</title>
<link href="http://www.kimroniny.top/2022/10/13/%E8%87%AA%E6%88%91%E5%AE%89%E6%85%B0-%E5%90%A7/"/>
<id>http://www.kimroniny.top/2022/10/13/%E8%87%AA%E6%88%91%E5%AE%89%E6%85%B0-%E5%90%A7/</id>
<published>2022-10-13T05:57:35.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>去 TMD 条条框框吧,洒脱一点!</p><span id="more"></span><p>要学会控制自己的关注点,在研究讨论的过程中,只考虑别人的文字,不考虑别人的情绪,不考虑情绪的目的是为了不被情绪所影响,也就是不要被别人的挤眉弄眼或者反问的语气所影响,可以把别人带有情绪的语言用自己的陈述句复述一遍,去思考其中的道理,多问自己几遍内容。</p><p>如果要解决“无法给老师讲清楚 idea ”的问题,就要多和老师讨论。这个问题的关键不在于我们讲的多么清楚、细致,而在于是否讲到了老师所关注的方向和粒度上。因此,必须要经常和老师交流,才能更加清晰的明白他们的关注点的维度,不能只靠自己闭门造车,要对全局范围内的各个对象有清楚的把握。</p>]]></content>
<summary type="html"><p>去 TMD 条条框框吧,洒脱一点!</p></summary>
<category term="fuck life" scheme="http://www.kimroniny.top/tags/fuck-life/"/>
</entry>
<entry>
<title>NAT简介</title>
<link href="http://www.kimroniny.top/2022/10/12/NAT%E7%AE%80%E4%BB%8B/"/>
<id>http://www.kimroniny.top/2022/10/12/NAT%E7%AE%80%E4%BB%8B/</id>
<published>2022-10-12T12:15:00.000Z</published>
<updated>2023-08-07T00:17:53.071Z</updated>
<content type="html"><![CDATA[<p>NAT 的相关知识</p><span id="more"></span><p>NAT(Network Address Translator,网络地址转换)是用于在本地网络中使用私有地址,在连接互联网时转而使用全局 IP 地址的技术。NAT实际上是为解决IPv4地址短缺而开发的技术。</p><p>即私有地址转换为公有地址(加端口)。</p><p>NAT 的特点:</p><ul><li>NAT 存在于私网到公网的路由出口位置,双向流量都必须经过 NAT 网关。</li><li>网络访问只能由私网向公网发起,公网无法访问私网。</li><li>NAT 需要维护一张关联表,保存会话信息,从而实现翻译功能。</li></ul><p>NAT 的类型:</p><ul><li>静态 NAT。一对一绑定转换。</li><li>动态 NAT。从空闲的地址池中选择一个进行转换。</li><li>端口复用 NATP。当私网内主机数量太多时,面临端口数量不足从而无法翻译的问题,此时,需要根据传输层或者其他上层协议去区分不同的会话,比如 TCP、UDP 端口号,从而实现公网 ip 的复用和解复用,</li></ul><p>NAT 的缺点:</p><ul><li>一旦 NAT 路由器重启,所有的 TCP 连接都会被重置断开。</li><li>关联表的生成和转换操作会产生一定的开销。</li><li>无法从 NAT 外部向内部服务器建立连接。</li></ul><p>参考:</p><ul><li><a href="https://blog.csdn.net/yingshuanglu2564/article/details/111830114">详解什么是NAT?</a></li></ul>]]></content>
<summary type="html"><p>NAT 的相关知识</p></summary>
<category term="network" scheme="http://www.kimroniny.top/categories/network/"/>
<category term="nat" scheme="http://www.kimroniny.top/categories/network/nat/"/>
<category term="network" scheme="http://www.kimroniny.top/tags/network/"/>
<category term="nat" scheme="http://www.kimroniny.top/tags/nat/"/>
</entry>
<entry>
<title>局域网间消息传递</title>
<link href="http://www.kimroniny.top/2022/10/12/%E5%B1%80%E5%9F%9F%E7%BD%91%E9%97%B4%E6%B6%88%E6%81%AF%E4%BC%A0%E9%80%92/"/>
<id>http://www.kimroniny.top/2022/10/12/%E5%B1%80%E5%9F%9F%E7%BD%91%E9%97%B4%E6%B6%88%E6%81%AF%E4%BC%A0%E9%80%92/</id>
<published>2022-10-12T11:47:59.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>局域网 IP 之间如何传递消息?</p><span id="more"></span><p>假设:</p><ul><li>腾讯服务器IP为118.89.97.19(当然实际会用域名,但经过DNS解析后还是IP,并且会又很多集群和部署在不同城市的机房)</li><li>家里的路由器拨号后有公网IP,不像校园网,分配的还是内网IP;</li><li>两个路由器公网IP分别为101.45.251.154、218.80.220.124;</li><li>登录时成功时,小明在自己电脑查看建立的TCP连接:<br />192.168.1.101:2099 118.89.97.19:80 establish</li><li>这只是一个假象,在腾讯服务器端查看到的连接是(端上IP和端口从192.168.1.101:2099变换成了路由器公网IP101.45.251.154和10000):<br />118.89.97.19:80 101.45.251.154:10000 establish</li><li>同理小明女朋友登录后也是同样的情况。<br />源IP 192.168.1.101|源端口2099|收件人、消息内容|目标IP 118.89.97.19|目标端口80</li></ul><p>数据包到达家里路由器,源IP地址会被NAT(了解更多请自己百度)更换成101.45.251.154,端口会被换成10000,然后经过层层转发到腾讯服务器,会得到“收件人、消息内容”的数据,然后入库并根据收件人将图片的数据,服务器检测到女朋友的账号又新消息到达时,从数据库读取消息,写入小明女朋友手机跟腾讯服务器之间的长连接通道,这时数据报文格式为:</p><p>源IP 118.89.97.19|源端口80|图片消息内容|目标IP 218.80.220.124|目标端口31214(女朋友手机聊天软件跟服务器通信时创建的端口)</p><p>消息同样经过层层转发到达女朋友家里的路由器,路由器根据端口31214,查到这个是需要发到女朋友手机上的,于是NAT把目标IP换成192.168.1.101,端口换成8888,于是手机收到消息并分发给聊天软件。</p><p>参考:</p><ul><li><a href="https://www.zhihu.com/question/64560386/answer/225743007">联网的软件是如何实现将消息从公网发送到内网的?</a></li></ul>]]></content>
<summary type="html"><p>局域网 IP 之间如何传递消息?</p></summary>
</entry>
<entry>
<title>软件设计流程</title>
<link href="http://www.kimroniny.top/2022/10/12/%E8%BD%AF%E4%BB%B6%E8%AE%BE%E8%AE%A1%E6%B5%81%E7%A8%8B/"/>
<id>http://www.kimroniny.top/2022/10/12/%E8%BD%AF%E4%BB%B6%E8%AE%BE%E8%AE%A1%E6%B5%81%E7%A8%8B/</id>
<published>2022-10-12T08:00:32.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>软件开发的五个阶段。</p><span id="more"></span><p>分析阶段, 设计阶段, 开发阶段, 测试阶段, 维护阶段。</p><h2 id="1-分析阶段"><a class="markdownIt-Anchor" href="#1-分析阶段"></a> 1. 分析阶段</h2><p>进行需求调研,提炼用户需求,建立完整的分析模式。</p><h2 id="2-设计阶段"><a class="markdownIt-Anchor" href="#2-设计阶段"></a> 2. 设计阶段</h2><p>主要分为:概要设计,详细设计。</p><h3 id="概要设计"><a class="markdownIt-Anchor" href="#概要设计"></a> 概要设计</h3><p>依照结构化设计方法进行设计。按照问题域,将软件逐级细化,分解为<strong>不必再分解的模块</strong>,每个模块完成一定的功能。模块,和子程序或者函数是对应的。</p><p>设计者会大致考虑模块的内部实现,但不用太纠结,聚焦在:确定功能,划分模块,定义调用关系。</p><p>调用关系(接口和参数)非常重要,必须在该阶段确定下来。</p><p>一般不会一次性到位,需要反复迭代调整。</p><p>需要完成的设计内容:</p><ul><li>数据字典。</li><li>数据流图。</li><li>结构图。</li><li>文字说明。</li></ul><h3 id="详细设计"><a class="markdownIt-Anchor" href="#详细设计"></a> 详细设计</h3><p>概要设计结束之后,针对各个模块,其详细设计可以并行执行。</p><p>根据概要设计的模块分解,设计每个模块内的算法、流程,描述模块内的具体功能。</p><p>如果详细设计的过程中有结构调整的必要,必须返还到概要设计阶段进行调整。</p><p>详细设计应该足够细致,能够根据该设计进行编码。</p><p>需要完成的设计内容:</p><ul><li>伪代码。</li><li>流程图。</li><li>PAD图。</li></ul><h2 id="3-开发阶段"><a class="markdownIt-Anchor" href="#3-开发阶段"></a> 3. 开发阶段</h2><p>各个模块根据详细设计进行编码。</p><p>开发过程中,先实现核心代码 demo,确定可以运行后,在模块中进行实现。</p><p>多打日志,能清晰看到各个子过程的中间输出。</p><p>做好注释,秉持着先注释后代码的原则,可以不写代码,但是注释必须要有,不只是诠释当前代码的作用,还要有 TODO BUG 等辅助信息。</p><p>每个功能函数在开发的过程中要为方便单元测试而进行设计。</p><p>善于运用 git 进行代码审核,每周都要进行代码审核,互相了解各模块间的开发进度和开发方式,及时调整不协调的环节。</p><h2 id="4-测试阶段"><a class="markdownIt-Anchor" href="#4-测试阶段"></a> 4. 测试阶段</h2><p>需要对程序进行单元、组装、系统三阶段的测试。</p><h2 id="5-维护阶段"><a class="markdownIt-Anchor" href="#5-维护阶段"></a> 5. 维护阶段</h2><p>软件研发完成并交付使用后,需要做好软件维护工作。</p><hr /><h2 id="参考"><a class="markdownIt-Anchor" href="#参考"></a> 参考:</h2><ol><li><a href="https://36kr.com/p/1508223783276551">软件开发流程五个阶段</a></li></ol>]]></content>
<summary type="html"><p>软件开发的五个阶段。</p></summary>
<category term="architect" scheme="http://www.kimroniny.top/categories/architect/"/>
<category term="software design" scheme="http://www.kimroniny.top/categories/architect/software-design/"/>
<category term="architect" scheme="http://www.kimroniny.top/tags/architect/"/>
<category term="software design" scheme="http://www.kimroniny.top/tags/software-design/"/>
</entry>
<entry>
<title>了解云原生</title>
<link href="http://www.kimroniny.top/2022/10/09/%E4%BA%86%E8%A7%A3%E4%BA%91%E5%8E%9F%E7%94%9F/"/>
<id>http://www.kimroniny.top/2022/10/09/%E4%BA%86%E8%A7%A3%E4%BA%91%E5%8E%9F%E7%94%9F/</id>
<published>2022-10-09T04:57:45.000Z</published>
<updated>2023-08-07T00:17:53.081Z</updated>
<content type="html"><![CDATA[<p>什么是云原生?要解决什么关键问题?</p><span id="more"></span><p>技术的变革,一定是思想先行。</p><p>Pivotal公司的Matt Stine于2013年首次提出云原生(CloudNative)的概念。</p><p>云原生是一种构建和运行应用程序的方法,是一套技术体系和方法论。</p><p>云原生(CloudNative)是一个组合词,Cloud+Native。<br />Cloud表示应用程序位于云中,而不是传统的数据中心;<br />Native表示应用程序从设计之初即考虑到云的环境,原生为云而设计,在云上以最佳姿势运行,<strong>充分利用和发挥云平台的弹性+分布式优势</strong>。</p><p>符合云原生架构的应用程序应该是:</p><ul><li>采用开源堆栈(K8S+Docker)进行容器化,</li><li>基于微服务架构提高灵活性和可维护性,</li><li>借助敏捷方法、DevOps支持持续迭代和运维自动化,</li><li>利用云平台设施实现弹性伸缩、动态调度、优化资源利用率</li></ul><p>云原生的四个要素:</p><ul><li><strong>微服务</strong>。几乎每个云原生的定义都包含微服务,跟微服务相对的是单体应用,微服务有理论基础,那就是康威定律。</li><li><strong>容器化</strong>。Docker 和 K8S(容器编排系统)。</li><li><strong>DevOps</strong>。Dev+Ops,就是开发和运维合体。</li><li><strong>持续交付</strong>。不误时开发,不停机更新,小步快跑,反传统瀑布式开发模型</li></ul><p>云计算是云原生的基础。</p><p>随着<strong>虚拟化技术的成熟和分布式框架的普及</strong>,在容器技术、可持续交付、编排系统等开源社区的推动下,以及微服务等开发理念的带动下,应用上云已经是不可逆转的趋势。</p><p>云计算三层:基础设施即服务(IaaS)、平台即服务(PaaS)、软件即服务(SaaS)。</p><p>真正的云化不仅仅是基础设施和平台的变化,应用也需要做出改变,摈弃传统的土方法,在<strong>架构设计、开发方式、部署维护等各个阶段和方面</strong>都基于云的特点,重新设计,从而建设全新的云化的应用,即云原生应用。</p><p>云的特点:</p><ul><li>编程语言。由传统的 c/c++、java 转换为<strong>以网络为中心</strong>的 go、nodejs 语言。</li><li>不停机更新。传统应用可能需要停机更新,但是<strong>云支持频繁变更</strong>,持续交付,蓝绿部署。</li><li>弹性资源。传统应用需要冗余资源以抵抗流量高峰,而云原生应用<strong>利用云的弹性自动伸缩</strong>,通过共享降本增效。</li><li>网络资源。传统应用对网络资源,比如ip、端口等有依赖,甚至是硬编码,而云原生应用对网络和存储都没有这种限制</li><li>运维。传统应用通常人肉部署手工运维,而云原生应用这一切都是<strong>自动化</strong>的。</li><li>系统环境。传统应用通常依赖系统环境,而云原生应用不会硬连接到任何系统环境,而是<strong>依赖抽象的基础架构</strong>,从而获得良好移植性</li><li>微服务。基于微服务架构的云原生应用,纵向划分服务,模块化更合理。</li></ul><p>软件设计有两个关键目标:<strong>高内聚、低耦合</strong>。</p><p>纵观近二十年的科技互联网发展历程,<strong>大的趋势是技术下沉</strong>,<br />特别是近些年,随着云计算的发展和普及,基础设施越来越厚实,<strong>业务开发变得越来越容易,也越来越没有技术含量</strong>,<br />而之前困扰小团队的性能、负载、安全性、扩展性问题都不复存在。</p><p>虽然不可否认技术的重要性在降低,但也还不至于那么悲观。<br />遥想PC时代,当VB、Delphi、MFC出现的时候,也有类似论调,所见即所得,点点鼠标,就可以开发PC桌面程序,是不是很高端?<br />那时候码农的担心相比现在恐怕是只多不少吧,<br />但后来随着互联网兴起,出现了后端开发这个工种,<br />码农很快找到了新的战场,网络、分布式、数据库、海量服务、容灾防错,<br />于是又玩出一堆新花样。</p><p>如果说PC时代的基础设施是控件库,互联网时代的基础实施是云,那AI时代基础设施是什么?又会有什么高端玩法?</p><p><a href="https://juejin.cn/post/6844904197859590151">原文链接</a></p>]]></content>
<summary type="html"><p>什么是云原生?要解决什么关键问题?</p></summary>
<category term="云计算" scheme="http://www.kimroniny.top/categories/%E4%BA%91%E8%AE%A1%E7%AE%97/"/>
<category term="云原生" scheme="http://www.kimroniny.top/categories/%E4%BA%91%E8%AE%A1%E7%AE%97/%E4%BA%91%E5%8E%9F%E7%94%9F/"/>
<category term="云原生" scheme="http://www.kimroniny.top/tags/%E4%BA%91%E5%8E%9F%E7%94%9F/"/>
<category term="云计算" scheme="http://www.kimroniny.top/tags/%E4%BA%91%E8%AE%A1%E7%AE%97/"/>
</entry>
</feed>