-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
664 lines (319 loc) · 309 KB
/
search.xml
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
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title></title>
<link href="/2019/08/09/golang/gin%E7%9A%84%E4%B8%80%E4%BA%9B%E6%80%BB%E7%BB%93/"/>
<url>/2019/08/09/golang/gin%E7%9A%84%E4%B8%80%E4%BA%9B%E6%80%BB%E7%BB%93/</url>
<content type="html"><![CDATA[<h2 id="gin非0取值注意:"><a href="#gin非0取值注意:" class="headerlink" title="gin非0取值注意:"></a>gin非0取值注意:</h2><p>如果想取bool类型的false,string类型的空字符串时,不能使用required<br>而应该用exist,否则会报数据未提交上来</p><figure class="highlight plain"><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">type AdminRoleJson struct {</span><br><span class="line">RoleName string `json:"role_name" binding:"required"`</span><br><span class="line">Remark string `json:"remark" binding:"exist"`</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>断言成功,则返回一个所断言的类型对象<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">claims,ok := user.(*util.Claims) //断言</span><br></pre></td></tr></table></figure></p>]]></content>
</entry>
<entry>
<title>搭建mongo副本集</title>
<link href="/2019/08/09/db/mongo_replicas/"/>
<url>/2019/08/09/db/mongo_replicas/</url>
<content type="html"><![CDATA[<p>[TOC]</p><p>##环境介绍</p><table><thead><tr><th>hostname</th><th>ip</th><th>mongo port</th></tr></thead><tbody><tr><td>a90</td><td>192.168.0.90</td><td>27019</td></tr><tr><td>a91</td><td>192.168.0.91</td><td>27019</td></tr><tr><td>a92</td><td>192.168.0.92</td><td>27019</td></tr></tbody></table><p>mongo版本:4.0<br>部署方式:docker手工部署</p><p>##目录</p>]]></content>
<categories>
<category> db </category>
</categories>
<tags>
<tag> mongo </tag>
</tags>
</entry>
<entry>
<title>prometheus监控mysql</title>
<link href="/2019/08/09/tools/prometheus-monitor-mysql_/"/>
<url>/2019/08/09/tools/prometheus-monitor-mysql_/</url>
<content type="html"><![CDATA[<ul><li><a href="#使用docker镜像运行prometheus">使用docker镜像运行prometheus</a></li><li><a href="#使用docker镜像运行mysqld_exporter">使用docker镜像运行mysqld_exporter</a></li><li><a href="#使用docker镜像运行grafana">使用docker镜像运行grafana</a></li><li><a href="#下载dashboard并导入grafana">下载dashboard并导入grafana</a></li></ul><h2 id="使用docker镜像运行prometheus"><a href="#使用docker镜像运行prometheus" class="headerlink" title="使用docker镜像运行prometheus"></a>使用docker镜像运行prometheus</h2><p>1.修改prometheus配置文件</p><figure class="highlight plain"><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"># my global config</span><br><span class="line">global:</span><br><span class="line"> scrape_interval: 15s</span><br><span class="line"> evaluation_interval: 30s</span><br><span class="line"> # scrape_timeout is set to the global default (10s).</span><br><span class="line"></span><br><span class="line">scrape_configs:</span><br><span class="line">- job_name: 'mysql'</span><br><span class="line"> static_configs:</span><br><span class="line"> - targets:</span><br><span class="line"> - x.x.x.x:9104</span><br><span class="line"> labels:</span><br><span class="line"> instance: myproject_mysql_cs</span><br><span class="line"> release: myproject_mysql_cs</span><br></pre></td></tr></table></figure><p>其中的X.X.X.X表示为mysqld_exporter所在的主机的IP</p><p>2.启动脚本<br><figure class="highlight plain"><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">#!/bin/bash</span><br><span class="line">name=prometheus</span><br><span class="line">docker stop ${name} && docker rm ${name}</span><br><span class="line">docker run --name ${name} -d -p 9090:9090 \</span><br><span class="line">-v /data/project/prometheus/conf/prometheus.yml:/etc/prometheus/prometheus.yml \</span><br><span class="line">-v /data/project/prometheus/data:/prometheus \</span><br><span class="line">-v /etc/localtime:/etc/localtime prom/prometheus</span><br></pre></td></tr></table></figure></p><h2 id="使用docker镜像运行mysqld-exporter"><a href="#使用docker镜像运行mysqld-exporter" class="headerlink" title="使用docker镜像运行mysqld_exporter"></a>使用docker镜像运行mysqld_exporter</h2><p>参考:<a href="https://github.com/prometheus/mysqld_exporter" target="_blank" rel="noopener">https://github.com/prometheus/mysqld_exporter</a></p><p>1.创建监控mysql的用户,并授权<br>如果不是用localhost连接的,需要把localhost换作export所在机器的IP<br>如果不限制连接的源IP,可以直接使用百分号:‘%’<br><figure class="highlight plain"><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">Required Grants</span><br><span class="line">CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'exporterpassword' WITH MAX_USER_CONNECTIONS 3;</span><br><span class="line">GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';</span><br></pre></td></tr></table></figure></p><p>2.启动mysqld_exporter</p><figure class="highlight plain"><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">#!/bin/bash</span><br><span class="line">name=mysqld-exporter</span><br><span class="line">docker stop ${name} && docker rm ${name}</span><br><span class="line">docker run -d \</span><br><span class="line"> --name ${name} \</span><br><span class="line"> --restart always \</span><br><span class="line"> -p 9104:9104 \</span><br><span class="line"> -e 'DATA_SOURCE_NAME=exporter:exporterpassword@tcp(100.100.100.100:3306)/' \</span><br><span class="line"> prom/mysqld-exporter</span><br></pre></td></tr></table></figure><h2 id="使用docker镜像运行grafana"><a href="#使用docker镜像运行grafana" class="headerlink" title="使用docker镜像运行grafana"></a>使用docker镜像运行grafana</h2><p>1.启动脚本<br><figure class="highlight plain"><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">#!/bin/bash</span><br><span class="line">name=grafana</span><br><span class="line">docker stop ${name} && docker rm ${name}</span><br><span class="line">docker run -d --name ${name} --restart always \</span><br><span class="line">-v /data/project/grafana:/var/lib/grafana \</span><br><span class="line">-p 3000:3000 grafana/grafana</span><br></pre></td></tr></table></figure></p><p>默认用户名密码:<br>admin/admin</p><h2 id="下载dashboard并导入grafana"><a href="#下载dashboard并导入grafana" class="headerlink" title="下载dashboard并导入grafana"></a>下载dashboard并导入grafana</h2><p>1.筛选了一下,这个下载还挺多的:<br>Mysql - Prometheusby Juan Chimienti<br>Basic Mysql dashboard for the prometheus exporter<br>PROMETHEUS<br>Downloads: 4262<br>Reviews: 0<br>下载地址:<a href="https://grafana.com/api/dashboards/6239/revisions/1/download" target="_blank" rel="noopener">https://grafana.com/api/dashboards/6239/revisions/1/download</a></p><p>2.有的仪表用负数表示,比如网络的收与发,看着不习惯,可以在所在的仪表中点edit->Visualization中修改</p>]]></content>
<categories>
<category> 工具 </category>
</categories>
<tags>
<tag> prometheus </tag>
</tags>
</entry>
<entry>
<title>ubuntu相关</title>
<link href="/2019/08/08/linux/ubuntu_/"/>
<url>/2019/08/08/linux/ubuntu_/</url>
<content type="html"><![CDATA[<ul><li><a href="#ubuntu1804server给eth0增加ip地址">ubuntu18.04server给eth0增加ip地址</a></li></ul><h2 id="ubuntu18-04server给eth0增加ip地址"><a href="#ubuntu18-04server给eth0增加ip地址" class="headerlink" title="ubuntu18.04server给eth0增加ip地址"></a>ubuntu18.04server给eth0增加ip地址</h2><p>参考:<a href="https://netplan.io/" target="_blank" rel="noopener">https://netplan.io/</a></p><p>cd /etc/netplan/<br>在这个目录下有网卡相关的yaml配置文件<br>cat /etc/netplan/99-eth0.yaml<br>直接添加一行 addresses: [x.x.x.x/x]<br>即可配置一个网卡新增一个IP<br><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">network:</span><br><span class="line"> version: 2</span><br><span class="line"> renderer: networkd</span><br><span class="line"> ethernets:</span><br><span class="line"> eth0:</span><br><span class="line"> dhcp4: no</span><br><span class="line"> match:</span><br><span class="line"> macaddress: 00:16:3e:01:2c:1c</span><br><span class="line"> addresses: [172.24.80.213/20]</span><br><span class="line"> addresses: [100.100.100.100/32]</span><br><span class="line"> gateway4: 172.24.95.253</span><br><span class="line"> routes:</span><br><span class="line"> - to: 0.0.0.0/0</span><br><span class="line"> via: 172.24.95.253</span><br><span class="line"> nameservers:</span><br><span class="line"> addresses: [ 100.100.2.138, 100.100.2.136 ]</span><br></pre></td></tr></table></figure></p>]]></content>
<categories>
<category> linux </category>
</categories>
<tags>
<tag> linux </tag>
<tag> ubuntu </tag>
</tags>
</entry>
<entry>
<title>redis sentinel集群搭建及监控</title>
<link href="/2019/08/07/db/redis-sentinel_/"/>
<url>/2019/08/07/db/redis-sentinel_/</url>
<content type="html"><![CDATA[<ul><li><a href="#搭建环境介绍">搭建环境介绍</a></li><li><a href="#redis各角色的启动脚本">redis各角色的启动脚本</a></li><li><a href="#sentinel配置文件">sentinel配置文件</a></li><li><a href="#redis集群状态变化的通知脚本">redis集群状态变化的通知脚本</a></li><li><a href="#搭建监控prometheusgrafanaredis_exporter">搭建监控prometheus+grafana+redis_exporter</a></li><li><a href="#参考">参考</a></li></ul><h2 id="搭建环境介绍"><a href="#搭建环境介绍" class="headerlink" title="搭建环境介绍"></a>搭建环境介绍</h2><p>在一台服务器上使用redis docker镜像安装集群测试环境<br>一主二从三哨兵:</p><table><thead><tr><th>ip</th><th>port</th><th>name</th><th>role</th></tr></thead><tbody><tr><td>10.0.1.200</td><td>6479</td><td>master</td><td>master</td></tr><tr><td>10.0.1.200</td><td>6579</td><td>slave01</td><td>slave</td></tr><tr><td>10.0.1.200</td><td>6679</td><td>slave02</td><td>slave</td></tr><tr><td>10.0.1.200</td><td>26479</td><td>sen01</td><td>sentinel</td></tr><tr><td>10.0.1.200</td><td>26579</td><td>sen02</td><td>sentinel</td></tr><tr><td>10.0.1.200</td><td>26679</td><td>sen03</td><td>sentinel</td></tr></tbody></table><h2 id="redis各角色的启动脚本"><a href="#redis各角色的启动脚本" class="headerlink" title="redis各角色的启动脚本"></a>redis各角色的启动脚本</h2><p>为了避免通告的IP和端口问题,docker容器的网络直接使用host<br>1_run_redis_master.sh<br><figure class="highlight plain"><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">#!/bin/bash</span><br><span class="line">name=master</span><br><span class="line">docker stop ${name} && docker rm ${name}</span><br><span class="line">docker run -d --name ${name} --net 'host' --restart always \</span><br><span class="line">-v /etc/localtime:/etc/localtime \</span><br><span class="line">-v /data/redis_sentinel/master_data:/data redis:5.0.5 \</span><br><span class="line">redis-server --port 6479</span><br></pre></td></tr></table></figure></p><p>2_run_redis_slave01.sh<br><figure class="highlight plain"><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">#!/bin/bash</span><br><span class="line">name=slave01</span><br><span class="line">docker stop ${name} && docker rm ${name}</span><br><span class="line">docker run -d --name ${name} --net 'host' --restart always \</span><br><span class="line">-v /etc/localtime:/etc/localtime \</span><br><span class="line">-v /data/redis_sentinel/slave01_data:/data redis:5.0.5 \</span><br><span class="line">redis-server --port 6579 --slaveof 10.0.1.200 6479</span><br></pre></td></tr></table></figure></p><p>3_run_redis_slave02.sh<br><figure class="highlight plain"><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">#!/bin/bash</span><br><span class="line">name=slave02</span><br><span class="line">docker stop ${name} && docker rm ${name}</span><br><span class="line">docker run -d --name ${name} --net 'host' --restart always</span><br><span class="line">-v /etc/localtime:/etc/localtime \</span><br><span class="line">-v /data/redis_sentinel/slave02_data:/data redis:5.0.5 \</span><br><span class="line">redis-server --port 6679 --slaveof 10.0.1.200 6479</span><br></pre></td></tr></table></figure></p><p>4_start_sen01.sh<br><figure class="highlight plain"><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">#!/bin/bash</span><br><span class="line">name="sen01"</span><br><span class="line">docker stop ${name} && docker rm ${name}</span><br><span class="line">docker run -d --name ${name} --net 'host' \</span><br><span class="line">-v /data/redis_sentinel/conf:/conf \</span><br><span class="line">redis:5.0.5 redis-server /conf/sentinel26479.conf --sentinel</span><br></pre></td></tr></table></figure></p><p>5_start_sen02.sh<br><figure class="highlight plain"><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">#!/bin/bash</span><br><span class="line">name="sen02"</span><br><span class="line">docker stop ${name} && docker rm ${name}</span><br><span class="line">docker run -d --name ${name} --net 'host' \</span><br><span class="line">-v /data/redis_sentinel/conf:/conf redis:5.0.5 \</span><br><span class="line">redis-server /conf/sentinel26579.conf --sentinel</span><br></pre></td></tr></table></figure></p><p>6_start_sen03.sh<br><figure class="highlight plain"><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">#!/bin/bash</span><br><span class="line">name="sen03"</span><br><span class="line">docker stop ${name} && docker rm ${name}</span><br><span class="line">docker run -d --name ${name} --net 'host' \</span><br><span class="line">-v /data/redis_sentinel/conf:/conf redis:5.0.5 \</span><br><span class="line">redis-server /conf/sentinel26679.conf --sentinel</span><br></pre></td></tr></table></figure></p><h2 id="sentinel配置文件"><a href="#sentinel配置文件" class="headerlink" title="sentinel配置文件"></a>sentinel配置文件</h2><p>从github获取redis sentinel配置文件<br>wget <a href="https://raw.githubusercontent.com/antirez/redis/unstable/sentinel.conf" target="_blank" rel="noopener">https://raw.githubusercontent.com/antirez/redis/unstable/sentinel.conf</a></p><p>为方便以后快速查看配置选项的含义,保留配置项的英文注释,修改配置文件如下:<br>sentinel26479.conf<br><figure class="highlight plain"><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><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br></pre></td><td class="code"><pre><span class="line">port 26479</span><br><span class="line">daemonize no</span><br><span class="line">pidfile "/var/run/redis-sentinel.pid"</span><br><span class="line">logfile ""</span><br><span class="line"></span><br><span class="line"># dir <working-directory></span><br><span class="line"># Every long running process should have a well-defined working directory.</span><br><span class="line"># For Redis Sentinel to chdir to /tmp at startup is the simplest thing</span><br><span class="line"># for the process to don't interfere with administrative tasks such as</span><br><span class="line"># unmounting filesystems.</span><br><span class="line">dir "/tmp"</span><br><span class="line"></span><br><span class="line"># sentinel monitor <master-name> <ip> <redis-port> <quorum></span><br><span class="line">#</span><br><span class="line"># Tells Sentinel to monitor this master, and to consider it in O_DOWN</span><br><span class="line"># (Objectively Down) state only if at least <quorum> sentinels agree.</span><br><span class="line">#</span><br><span class="line"># Note that whatever is the ODOWN quorum, a Sentinel will require to</span><br><span class="line"># be elected by the majority of the known Sentinels in order to</span><br><span class="line"># start a failover, so no failover can be performed in minority.</span><br><span class="line">#</span><br><span class="line"># Replicas are auto-discovered, so you don't need to specify replicas in</span><br><span class="line"># any way. Sentinel itself will rewrite this configuration file adding</span><br><span class="line"># the replicas using additional configuration options.</span><br><span class="line"># Also note that the configuration file is rewritten when a</span><br><span class="line"># replica is promoted to master.</span><br><span class="line">#</span><br><span class="line"># Note: master name should not include special characters or spaces.</span><br><span class="line"># The valid charset is A-z 0-9 and the three characters ".-_".</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># Number of milliseconds the master (or any attached replica or sentinel) should</span><br><span class="line"># be unreachable (as in, not acceptable reply to PING, continuously, for the</span><br><span class="line"># specified period) in order to consider it in S_DOWN state (Subjectively</span><br><span class="line"># Down).</span><br><span class="line">#</span><br><span class="line"># Default is 30 seconds.</span><br><span class="line"></span><br><span class="line">sentinel deny-scripts-reconfig yes</span><br><span class="line"></span><br><span class="line"># sentinel parallel-syncs <master-name> <numreplicas></span><br><span class="line">#</span><br><span class="line"># How many replicas we can reconfigure to point to the new replica simultaneously</span><br><span class="line"># during the failover. Use a low number if you use the replicas to serve query</span><br><span class="line"># to avoid that all the replicas will be unreachable at about the same</span><br><span class="line"># time while performing the synchronization with the master.</span><br><span class="line"></span><br><span class="line">sentinel monitor mymaster 10.0.1.200 6479 2</span><br><span class="line"></span><br><span class="line"># sentinel failover-timeout <master-name> <milliseconds></span><br><span class="line">#</span><br><span class="line"># Specifies the failover timeout in milliseconds. It is used in many ways:</span><br><span class="line">#</span><br><span class="line"># - The time needed to re-start a failover after a previous failover was</span><br><span class="line"># already tried against the same master by a given Sentinel, is two</span><br><span class="line"># times the failover timeout.</span><br><span class="line">#</span><br><span class="line"># - The time needed for a replica replicating to a wrong master according</span><br><span class="line"># to a Sentinel current configuration, to be forced to replicate</span><br><span class="line"># with the right master, is exactly the failover timeout (counting since</span><br><span class="line"># the moment a Sentinel detected the misconfiguration).</span><br><span class="line">#</span><br><span class="line"># - The time needed to cancel a failover that is already in progress but</span><br><span class="line"># did not produced any configuration change (SLAVEOF NO ONE yet not</span><br><span class="line"># acknowledged by the promoted replica).</span><br><span class="line">#</span><br><span class="line"># - The maximum time a failover in progress waits for all the replicas to be</span><br><span class="line"># reconfigured as replicas of the new master. However even after this time</span><br><span class="line"># the replicas will be reconfigured by the Sentinels anyway, but not with</span><br><span class="line"># the exact parallel-syncs progression as specified.</span><br><span class="line">#</span><br><span class="line"># Default is 3 minutes.</span><br><span class="line"></span><br><span class="line">sentinel down-after-milliseconds mymaster 5000</span><br><span class="line"></span><br><span class="line"># NOTIFICATION SCRIPT</span><br><span class="line">#</span><br><span class="line"># sentinel notification-script <master-name> <script-path></span><br><span class="line">#</span><br><span class="line"># Call the specified notification script for any sentinel event that is</span><br><span class="line"># generated in the WARNING level (for instance -sdown, -odown, and so forth).</span><br><span class="line"># This script should notify the system administrator via email, SMS, or any</span><br><span class="line"># other messaging system, that there is something wrong with the monitored</span><br><span class="line"># Redis systems.</span><br><span class="line">#</span><br><span class="line"># The script is called with just two arguments: the first is the event type</span><br><span class="line"># and the second the event description.</span><br><span class="line">#</span><br><span class="line"># The script must exist and be executable in order for sentinel to start if</span><br><span class="line"># this option is provided.</span><br><span class="line"></span><br><span class="line">sentinel notification-script mymaster /conf/notify.sh</span><br><span class="line">sentinel config-epoch mymaster 0</span><br><span class="line"># Generated by CONFIG REWRITE</span><br><span class="line">sentinel leader-epoch mymaster 0</span><br><span class="line">sentinel known-replica mymaster 10.0.1.200 6679</span><br><span class="line">sentinel known-replica mymaster 10.0.1.200 6579</span><br><span class="line">sentinel current-epoch 0</span><br></pre></td></tr></table></figure></p><p>sentinel26579.conf<br><figure class="highlight plain"><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">port 26579</span><br><span class="line">daemonize no</span><br><span class="line">pidfile "/var/run/redis-sentinel.pid"</span><br><span class="line">logfile ""</span><br><span class="line">dir "/tmp"</span><br><span class="line">sentinel deny-scripts-reconfig yes</span><br><span class="line">sentinel monitor mymaster 10.0.1.200 6479 2</span><br><span class="line">sentinel down-after-milliseconds mymaster 5000</span><br><span class="line">sentinel notification-script mymaster /conf/notify.sh</span><br><span class="line">sentinel config-epoch mymaster 0</span><br><span class="line">sentinel leader-epoch mymaster 0</span><br><span class="line">sentinel known-replica mymaster 10.0.1.200 6679</span><br><span class="line">sentinel known-replica mymaster 10.0.1.200 6579</span><br><span class="line">sentinel current-epoch 0</span><br></pre></td></tr></table></figure></p><p>sentinel26679.conf<br><figure class="highlight plain"><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">port 26679</span><br><span class="line">daemonize no</span><br><span class="line">pidfile "/var/run/redis-sentinel.pid"</span><br><span class="line">logfile ""</span><br><span class="line">dir "/tmp"</span><br><span class="line">sentinel deny-scripts-reconfig yes</span><br><span class="line">sentinel monitor mymaster 10.0.1.200 6479 2</span><br><span class="line">sentinel down-after-milliseconds mymaster 5000</span><br><span class="line">sentinel notification-script mymaster /conf/notify.sh</span><br><span class="line">sentinel config-epoch mymaster 0</span><br><span class="line">sentinel leader-epoch mymaster 0</span><br><span class="line">sentinel known-replica mymaster 10.0.1.200 6579</span><br><span class="line">sentinel known-replica mymaster 10.0.1.200 6679</span><br><span class="line">sentinel current-epoch 0</span><br></pre></td></tr></table></figure></p><h2 id="redis集群状态变化的通知脚本"><a href="#redis集群状态变化的通知脚本" class="headerlink" title="redis集群状态变化的通知脚本"></a>redis集群状态变化的通知脚本</h2><p>由于官方的redis镜像中没有curl命令,所以自己动手用golang写个简单的http POST字符串的脚本编译成gohttppost,<br>调用钉钉的webhook机器人,达到通知的目的,golang脚本参见:<br>使用go发送http POST请求:<a href="https://gitrootid.github.io/2019/08/07/golang/go-http-post_/">https://gitrootid.github.io/2019/08/07/golang/go-http-post_/</a></p><p>notify.sh<br><figure class="highlight plain"><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">#!/bin/bash</span><br><span class="line">dir=$(dirname "$0")</span><br><span class="line">cd ${dir}</span><br><span class="line">dir=`pwd`</span><br><span class="line">cd ${dir}</span><br><span class="line"></span><br><span class="line">event_type=$1</span><br><span class="line">event_description=$2</span><br><span class="line"></span><br><span class="line">topic='redis-sentinel-notification'</span><br><span class="line">content='topic:'${topic}',event:'${event_type}',description:'${event_description}</span><br><span class="line">ding_talk_url='https://oapi.dingtalk.com/robot/send?access_token=XXX'</span><br><span class="line">MSG='{"msgtype": "text","text": {"content": "'${content}'"}}'</span><br><span class="line">./gohttppost -u "${ding_talk_url}" -b "${MSG}" -s true</span><br></pre></td></tr></table></figure></p><p>至此集群搭建完成</p><h2 id="redis相关命令"><a href="#redis相关命令" class="headerlink" title="redis相关命令"></a>redis相关命令</h2><p>1.info查看集群相关信息<br><figure class="highlight plain"><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">docker exec -it sen01 /bin/bash</span><br><span class="line">redis-cli -p 26679</span><br><span class="line">>info</span><br></pre></td></tr></table></figure></p><p>2.monitor命令可以查看redis服务器正在执行的所有命令<br> 注意:由于monitor命令返回服务器处理的所有的命令, 所以在性能上会有一些消耗.<br>3.save阻塞式数据持久化<br>4.bgsave非阻塞式数据持久化</p><h2 id="搭建监控prometheus-grafana-redis-exporter"><a href="#搭建监控prometheus-grafana-redis-exporter" class="headerlink" title="搭建监控prometheus+grafana+redis_exporter"></a>搭建监控prometheus+grafana+redis_exporter</h2><p>参考:<a href="https://github.com/oliver006/redis_exporter" target="_blank" rel="noopener">https://github.com/oliver006/redis_exporter</a><br>修改prometheus配置文件<br><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line"># my global config</span><br><span class="line">global:</span><br><span class="line"> scrape_interval: 15s</span><br><span class="line"> evaluation_interval: 30s</span><br><span class="line"> # scrape_timeout is set to the global default (10s).</span><br><span class="line"></span><br><span class="line">scrape_configs:</span><br><span class="line"></span><br><span class="line">- job_name: redis_irs_cs</span><br><span class="line"> static_configs:</span><br><span class="line"> - targets:</span><br><span class="line"> - redis://10.0.1.200:6479</span><br><span class="line"> - redis://10.0.1.200:6579</span><br><span class="line"> - redis://10.0.1.200:6679</span><br><span class="line"> metrics_path: /scrape</span><br><span class="line"> relabel_configs:</span><br><span class="line"> - source_labels: [__address__]</span><br><span class="line"> target_label: __param_target</span><br><span class="line"> - source_labels: [__param_target]</span><br><span class="line"> target_label: addr</span><br><span class="line"> - target_label: __address__</span><br><span class="line"> replacement: 10.0.1.200:9121</span><br></pre></td></tr></table></figure></p><p>使用docker镜像运行prometheus<br><figure class="highlight plain"><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">#!/bin/bash</span><br><span class="line">name=prometheus</span><br><span class="line">docker stop ${name} && docker rm ${name}</span><br><span class="line">docker run --name ${name} -d -p 9090:9090 \</span><br><span class="line">-v /data/project/prometheus/conf/prometheus.yml:/etc/prometheus/prometheus.yml \</span><br><span class="line">-v /data/project/prometheus/data:/prometheus \</span><br><span class="line">-v /etc/localtime:/etc/localtime prom/prometheus</span><br></pre></td></tr></table></figure></p><p>使用docker镜像运行redis_exporter<br>1.0版本支持直接把redis_exporter作为黑盒运行,不用关心配置<br><figure class="highlight plain"><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">#!/bin/bash</span><br><span class="line">name=redis_exporter</span><br><span class="line">docker stop ${name} && docker rm ${name}</span><br><span class="line">docker run -d --name ${name} --restart always -p 9121:9121 oliver006/redis_exporter</span><br></pre></td></tr></table></figure></p><p>使用docker镜像运行grafana<br><figure class="highlight plain"><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">#!/bin/bash</span><br><span class="line">name=grafana</span><br><span class="line">docker stop ${name} && docker rm ${name}</span><br><span class="line">docker run -d --name ${name} --restart always \</span><br><span class="line">-v /data/project/grafana:/var/lib/grafana \</span><br><span class="line">-p 3000:3000 grafana/grafana</span><br></pre></td></tr></table></figure></p><p>默认用户名密码:<br>admin/admin</p><p>登陆后导入从grafana官网下载的redis dashboard仪表盘:<a href="https://grafana.com/api/dashboards/2751/revisions/1/download" target="_blank" rel="noopener">https://grafana.com/api/dashboards/2751/revisions/1/download</a><br>然后在configuration里配置datasource,再进入prometheus-redis的dashboard,就可以看到漂亮的各指标界面了</p><p>prometheus的报警规则以后再增加</p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p><a href="https://redis.io/topics/sentinel" target="_blank" rel="noopener">https://redis.io/topics/sentinel</a><br><a href="https://gist.github.com/ylgrgyq/89f3aeae294dda340c74e202c00aa1f7" target="_blank" rel="noopener">https://gist.github.com/ylgrgyq/89f3aeae294dda340c74e202c00aa1f7</a><br><a href="https://segmentfault.com/a/1190000002685515" target="_blank" rel="noopener">https://segmentfault.com/a/1190000002685515</a></p>]]></content>
<categories>
<category> db </category>
</categories>
<tags>
<tag> redis </tag>
</tags>
</entry>
<entry>
<title>使用go发送http POST请求</title>
<link href="/2019/08/07/golang/go-http-post_/"/>
<url>/2019/08/07/golang/go-http-post_/</url>
<content type="html"><![CDATA[<ul><li><a href="#使用场景">使用场景</a></li><li><a href="#简单实现post字符串">简单实现POST字符串</a></li><li><a href="#编译脚本">编译脚本</a></li></ul><h2 id="使用场景"><a href="#使用场景" class="headerlink" title="使用场景"></a>使用场景</h2><p>主要用于需要简单的POST一串字符串到某服务器,但是curl命令又没有的安装的情况,比如docker镜像中</p><h2 id="简单实现POST字符串"><a href="#简单实现POST字符串" class="headerlink" title="简单实现POST字符串"></a>简单实现POST字符串</h2><figure class="highlight go"><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><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line"><span class="string">"bytes"</span></span><br><span class="line"><span class="string">"crypto/tls"</span></span><br><span class="line"><span class="string">"flag"</span></span><br><span class="line"><span class="string">"fmt"</span></span><br><span class="line"><span class="string">"io/ioutil"</span></span><br><span class="line"><span class="string">"net/http"</span></span><br><span class="line"><span class="string">"os"</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> (</span><br><span class="line">s <span class="keyword">bool</span></span><br><span class="line">h <span class="keyword">bool</span></span><br><span class="line">t <span class="keyword">string</span></span><br><span class="line">b <span class="keyword">string</span></span><br><span class="line">resp *http.Response</span><br><span class="line">err error</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">init</span><span class="params">()</span></span> {</span><br><span class="line">flag.BoolVar(&h, <span class="string">"h"</span>, <span class="literal">false</span>, <span class="string">"this help"</span>)</span><br><span class="line">flag.BoolVar(&s, <span class="string">"s"</span>, <span class="literal">false</span>, <span class="string">"Insecure SSL Skip Verify, default false"</span>)</span><br><span class="line"></span><br><span class="line">flag.StringVar(&t, <span class="string">"u"</span>, <span class="string">""</span>, <span class="string">"url"</span>)</span><br><span class="line">flag.StringVar(&b, <span class="string">"b"</span>, <span class="string">""</span>, <span class="string">"'{\"key\":\"value\"}'"</span>)</span><br><span class="line"><span class="comment">// 改变默认的 Usage,flag包中的Usage 其实是一个函数类型。这里是覆盖默认函数实现,具体见后面Usage部分的分析</span></span><br><span class="line">flag.Usage = usage</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">usage</span><span class="params">()</span></span> {</span><br><span class="line">fmt.Fprintf(os.Stderr, <span class="string">`http POST application/json</span></span><br><span class="line"><span class="string">Usage: gohttppost [-h] [-u url] [-b body]</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">Options:</span></span><br><span class="line"><span class="string">`</span>)</span><br><span class="line">flag.PrintDefaults()</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">flag.Parse()</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> h {</span><br><span class="line">flag.Usage()</span><br><span class="line">os.Exit(<span class="number">0</span>)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">payloadBytes := []<span class="keyword">byte</span>(b)</span><br><span class="line">body := bytes.NewReader(payloadBytes)</span><br><span class="line">req, err := http.NewRequest(<span class="string">"POST"</span>, t, body)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line">fmt.Println(<span class="string">"err:"</span>, <span class="string">"http.NewRequest:"</span>, err)</span><br><span class="line">}</span><br><span class="line">req.Header.Set(<span class="string">"Content-Type"</span>, <span class="string">"application/json"</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 判断是否校验SSL证书</span></span><br><span class="line"><span class="keyword">if</span> s {</span><br><span class="line">tr := &http.Transport{</span><br><span class="line">TLSClientConfig: &tls.Config{InsecureSkipVerify: <span class="literal">true</span>},</span><br><span class="line">}</span><br><span class="line">client := http.Client{Transport: tr}</span><br><span class="line">resp, err = client.Do(req)</span><br><span class="line"></span><br><span class="line">} <span class="keyword">else</span> {</span><br><span class="line">resp, err = http.DefaultClient.Do(req)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line">fmt.Println(<span class="string">"err:"</span>, <span class="string">"http client request:"</span>, err)</span><br><span class="line">}</span><br><span class="line"><span class="keyword">defer</span> resp.Body.Close()</span><br><span class="line">fmt.Println(<span class="string">"response Status:"</span>, resp.Status)</span><br><span class="line">resBody, _ := ioutil.ReadAll(resp.Body)</span><br><span class="line">fmt.Println(<span class="string">"response Body:"</span>, <span class="keyword">string</span>(resBody))</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="编译脚本"><a href="#编译脚本" class="headerlink" title="编译脚本"></a>编译脚本</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></pre></td><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line">CGO_ENABLED=0 GOOS=linux go build -a -ldflags <span class="string">"-w"</span> -o gohttppost main.go</span><br><span class="line"></span><br><span class="line"><span class="comment"># -a 强制编译所有依赖包。</span></span><br><span class="line"><span class="comment"># -s 去掉符号信息</span></span><br><span class="line"><span class="comment"># -w 去掉DWARF调试信息,得到的程序就不能用gdb调试了</span></span><br><span class="line"><span class="comment"># 不建议s和w同时使用。</span></span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> golang </category>
</categories>
<tags>
<tag> go </tag>
<tag> golang </tag>
</tags>
</entry>
<entry>
<title>install keepalived</title>
<link href="/2019/07/30/tools/install-keepalived_/"/>
<url>/2019/07/30/tools/install-keepalived_/</url>
<content type="html"><![CDATA[<ul><li><a href="#需求">需求</a></li><li><a href="#源码安装keepalived">源码安装keepalived</a></li><li><a href="#配置负载均衡">配置负载均衡</a></li><li><a href="#配置realserver">配置realserver</a></li><li><a href="#启动keepalived">启动keepalived</a></li><li><a href="#验证">验证</a></li></ul><h1 id="需求"><a href="#需求" class="headerlink" title="需求"></a>需求</h1><p>1.有4台服务器,如下</p><table><thead><tr><th>hostname</th><th>ip</th><th>作用</th></tr></thead><tbody><tr><td>test1</td><td>10.0.1.201</td><td>keepalived master</td></tr><tr><td>test2</td><td>10.0.1.202</td><td>keepalived backup</td></tr><tr><td>real1</td><td>10.0.1.203</td><td>realserver 1,安装nginx</td></tr><tr><td>real2</td><td>10.0.1.204</td><td>realserver 2,安装nginx</td></tr></tbody></table><p>2.本次试验的虚拟IP:10.0.1.200</p><p>3.4台服务器同处于一个局域网中<br>4.要求:同一时间只能有一台服务器的nginx处理请求流量,假如现在是real2在处理请求,real1处于standby状态,将real2的nginx关闭,real1自动接管real2的流量</p><h1 id="源码安装keepalived"><a href="#源码安装keepalived" class="headerlink" title="源码安装keepalived"></a>源码安装keepalived</h1><figure class="highlight plain"><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">wget https://www.keepalived.org/software/keepalived-2.0.17.tar.gz</span><br><span class="line">tar xf keepalived-2.0.17.tar.gz</span><br><span class="line">cd keepalived-2.0.17/</span><br><span class="line">mkdir /opt/keepalived</span><br><span class="line">./configure --prefix=/opt/keepalived</span><br><span class="line">make -j2</span><br><span class="line">make install</span><br><span class="line"># 安装完成</span><br></pre></td></tr></table></figure><h1 id="配置负载均衡"><a href="#配置负载均衡" class="headerlink" title="配置负载均衡"></a>配置负载均衡</h1><p>1.修改配置文件<br>/opt/keepalived/etc/keepalived/keepalived.conf</p><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">! Configuration File for keepalived</span><br><span class="line"></span><br><span class="line">global_defs {</span><br><span class="line"></span><br><span class="line"> router_id LVS_TEST_1</span><br><span class="line"> vrrp_skip_check_adv_addr</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">vrrp_instance VI_1 {</span><br><span class="line"> state MASTER</span><br><span class="line"> interface eth0</span><br><span class="line"> virtual_router_id 51</span><br><span class="line"> priority 150</span><br><span class="line"> advert_int 1</span><br><span class="line"> authentication {</span><br><span class="line"> auth_type PASS</span><br><span class="line"> auth_pass 1111</span><br><span class="line"> }</span><br><span class="line"> virtual_ipaddress {</span><br><span class="line"> 10.0.1.200</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">virtual_server 10.0.1.200 80 {</span><br><span class="line"> delay_loop 6 #设置健康检查时间,单位是秒</span><br><span class="line"> lb_algo fo # 设置负载调度算法,为了满足其中一台服务器只是作热备,这里使用fo算法,非常关键</span><br><span class="line"> lb_kind DR #设置LVS实现LB机制,有NAT、TUNN和DR三个模式可选</span><br><span class="line"> #persistence_timeout 50 #保持客户端的请求在这个时间段内全部发到同一个真实服务器,单位为秒</span><br><span class="line"> protocol TCP</span><br><span class="line"></span><br><span class="line"> real_server 10.0.1.203 80 {</span><br><span class="line"> weight 1</span><br><span class="line"> TCP_CHECK { </span><br><span class="line"> connect_timeout 2 #表示2秒无响应,则超时 </span><br><span class="line"> retry 2 #表示重试次数 </span><br><span class="line"> delay_before_retry 1 #表示重试间隔 </span><br><span class="line"> connect_port 80</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> real_server 10.0.1.204 80 {</span><br><span class="line"> weight 2 # 如果没看错的话,fo算法是从权重最高的之中选一台作为负载服务器</span><br><span class="line"> TCP_CHECK { </span><br><span class="line"> connect_timeout 2 #表示2秒无响应,则超时 </span><br><span class="line"> retry 2 #表示重试次数 </span><br><span class="line"> delay_before_retry 1 #表示重试间隔 </span><br><span class="line"> connect_port 80</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>2.将keepalived的目录/opt/keepalived整个复制到test2,并只修改其中的三项:<br>state,router_id,priority<br>state为backup的服务器,其priority必须要小于master服务器的priority值</p><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">! Configuration File for keepalived</span><br><span class="line"></span><br><span class="line">global_defs {</span><br><span class="line"></span><br><span class="line"> router_id LVS_TEST_2</span><br><span class="line"> vrrp_skip_check_adv_addr</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">vrrp_instance VI_1 {</span><br><span class="line"> state BACKUP</span><br><span class="line"> interface eth0</span><br><span class="line"> virtual_router_id 51</span><br><span class="line"> priority 100</span><br><span class="line"> advert_int 1</span><br><span class="line"></span><br><span class="line"> authentication {</span><br><span class="line"> auth_type PASS</span><br><span class="line"> auth_pass 1111</span><br><span class="line"> }</span><br><span class="line"> virtual_ipaddress {</span><br><span class="line"> 10.0.1.200</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">virtual_server 10.0.1.200 80 {</span><br><span class="line"> delay_loop 6 #设置健康检查时间,单位是秒</span><br><span class="line"> lb_algo fo # 设置负载调度算法,为了满足其中一台服务器只是作热备,这里使用fo算法,非常关键</span><br><span class="line"> lb_kind DR #设置LVS实现LB机制,有NAT、TUNN和DR三个模式可选</span><br><span class="line"> #persistence_timeout 50 #保持客户端的请求在这个时间段内全部发到同一个真实服务器,单位为秒</span><br><span class="line"> protocol TCP</span><br><span class="line"></span><br><span class="line"> real_server 10.0.1.203 80 {</span><br><span class="line"> weight 1</span><br><span class="line"> TCP_CHECK { </span><br><span class="line"> connect_timeout 2 #表示2秒无响应,则超时 </span><br><span class="line"> retry 2 #表示重试次数 </span><br><span class="line"> delay_before_retry 1 #表示重试间隔 </span><br><span class="line"> connect_port 80</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> real_server 10.0.1.204 80 {</span><br><span class="line"> weight 2</span><br><span class="line"> TCP_CHECK { </span><br><span class="line"> connect_timeout 2 #表示2秒无响应,则超时 </span><br><span class="line"> retry 2 #表示重试次数 </span><br><span class="line"> delay_before_retry 1 #表示重试间隔 </span><br><span class="line"> connect_port 80</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><p>3.打开内核转发<br><figure class="highlight plain"><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">sudo sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf</span><br><span class="line">sysctl -p</span><br></pre></td></tr></table></figure></p><h1 id="配置realserver"><a href="#配置realserver" class="headerlink" title="配置realserver"></a>配置realserver</h1><p>1.由于是DR转发,所以realserver需要arp抑制<br>分别在real1和real2上执行<br><figure class="highlight plain"><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">#!/bin/bash</span><br><span class="line">echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore </span><br><span class="line">echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce </span><br><span class="line">echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore </span><br><span class="line">echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce</span><br></pre></td></tr></table></figure></p><p>2.配置vip到realserver的lo:0接口</p><p>分别在real1和real2上执行<br><figure class="highlight plain"><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">VIP=‘10.0.1.200’</span><br><span class="line">ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast $VIP</span><br><span class="line">route add -host $VIP dev lo:0</span><br></pre></td></tr></table></figure></p><p>3.为了快捷,使用docker启动nginx<br>分别在real1和real2上执行:<br><figure class="highlight plain"><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">docker run -d --name nginx -p 80:80 -v /opt/html:/usr/share/nginx/html nginx</span><br><span class="line">hostname > /opt/html/index.html</span><br><span class="line"># 为了测试效果,把主机名作为请求返回的结果,以确定是哪个服务器响应的请求</span><br></pre></td></tr></table></figure></p><p>docker运行后,验证一下网嶡请求是否能正常返回:<br>curl 10.0.1.203<br>curl 10.0.1.204</p><h1 id="启动keepalived"><a href="#启动keepalived" class="headerlink" title="启动keepalived"></a>启动keepalived</h1><p>分别在test1和test2上执行<br><figure class="highlight plain"><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">#!/bin/bash</span><br><span class="line">/opt/keepalived/sbin/keepalived -f /opt/keepalived/etc/keepalived/keepalived.conf</span><br></pre></td></tr></table></figure></p><h1 id="验证"><a href="#验证" class="headerlink" title="验证"></a>验证</h1><p>1.模拟一切OK的情况<br>curl 10.0.1.200<br>请求N次,返回的结果都为real2的主机名,为符合预期结果:同一时间,只能一台服务器提供服务<br>2.模拟real2的nginx异常退出的情况<br>在real2上执行:docker stop nginx,然后执行:curl 10.0.1.200<br>请求N次,返回的结果都为real1的主机名,为符合预期结果:将real2的nginx关闭,real1自动接管real2的流量</p><p>3.恢复一切正常后,再模拟keepalived master异常退出的情况<br>将test1的keepalived进程杀掉:killall keepalived<br>然后执行N次:curl 10.0.1.200<br>返回的结果都为real2的主机名,为符合预期结果:同一时间,只能一台服务器提供服务</p><p>4.恢复一切正常后,再模拟keepalived master服务器宕机的情况<br>将test1的keepalived进程杀掉:killall keepalived<br>将real2的nginx关闭:docker stop nginx<br>然后执行N次:curl 10.0.1.200<br>返回的结果都为real1的主机名,为符合预期结果:将real2的nginx关闭,real1自动接管real2的流量</p><p>5.恢复一切正常后,再模拟keepalived backup服务器宕机的情况<br>将test2的keepalived进程杀掉:killall keepalived<br>将real2的nginx关闭:docker stop nginx<br>然后执行N次:curl 10.0.1.200<br>返回的结果都为real1的主机名,为符合预期结果:将real2的nginx关闭,real1自动接管real2的流量</p>]]></content>
<categories>
<category> 工具 </category>
</categories>
<tags>
<tag> keepalived </tag>
</tags>
</entry>
<entry>
<title>go gin uploadfile</title>
<link href="/2019/06/13/golang/go-gin-uploadfile_/"/>
<url>/2019/06/13/golang/go-gin-uploadfile_/</url>
<content type="html"><![CDATA[<ul><li><a href="#uploadfile">uploadfile</a></li></ul><h2 id="uploadfile"><a href="#uploadfile" class="headerlink" title="uploadfile"></a>uploadfile</h2><p>Gin 对接受用户上传的文件做了友好的处理,在 Handler 中可以很简单的实现文件的接收。</p><p>要注意的是,上传文件的大小有限制,通常是 <32MB,你可以使用 router.MaxMultipartMemory更改它。</p><figure class="highlight go"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//Deferred Cleanup, Checking Errors, and Potential Problems</span></span><br><span class="line"><span class="comment">//refer to:https://blevesearch.com/news/Deferred-Cleanup,-Checking-Errors,-and-Potential-Problems/</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Close</span><span class="params">(c io.Closer)</span></span> {</span><br><span class="line">err := c.Close()</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line">log.Fatal(err)</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">router := gin.Default()</span><br><span class="line"><span class="comment">// 设置文件上传大小 router.MaxMultipartMemory = 8 << 20 // 8 MiB</span></span><br><span class="line"><span class="comment">// 处理单一的文件上传</span></span><br><span class="line">router.POST(<span class="string">"/upload"</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> {</span><br><span class="line"><span class="comment">// 拿到这个文件</span></span><br><span class="line">file, header, _ := c.Request.FormFile(<span class="string">"file"</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">//getType := reflect.TypeOf(header)</span></span><br><span class="line"><span class="comment">//fmt.Println("get Type is :", getType.Name())</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//getValue := reflect.ValueOf(header)</span></span><br><span class="line"><span class="comment">//fmt.Println("get all Fields is:", getValue)</span></span><br><span class="line"></span><br><span class="line">log.Println(<span class="string">"size:"</span>, header.Size)</span><br><span class="line"></span><br><span class="line">fh, err := os.Create(header.Filename)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line">log.Fatal(err)</span><br><span class="line">}</span><br><span class="line"><span class="keyword">defer</span> Close(fh)</span><br><span class="line">_, err1 := io.Copy(fh, file)</span><br><span class="line"><span class="keyword">if</span> err1 != <span class="literal">nil</span> {</span><br><span class="line">log.Fatal(err1)</span><br><span class="line">}</span><br><span class="line">c.String(http.StatusOK, fmt.Sprintf(<span class="string">"'%s' uploaded!"</span>, header.Filename))</span><br><span class="line">})</span><br><span class="line"></span><br><span class="line"><span class="comment">// 处理多个文件的上传</span></span><br><span class="line">router.POST(<span class="string">"/uploads"</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> {</span><br><span class="line">form, _ := c.MultipartForm()</span><br><span class="line"><span class="comment">// 拿到集合</span></span><br><span class="line">files := form.File[<span class="string">"upload[]"</span>]</span><br><span class="line"><span class="keyword">for</span> _, file := <span class="keyword">range</span> files {</span><br><span class="line">log.Println(file.Filename)</span><br><span class="line">}</span><br><span class="line">c.String(http.StatusOK, fmt.Sprintf(<span class="string">"%d files uploaded!"</span>, <span class="built_in">len</span>(files)))</span><br><span class="line">})</span><br><span class="line">router.Run(<span class="string">":8080"</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>用 curl 工具测试一下:</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></pre></td><td class="code"><pre><span class="line"><span class="comment"># 单一文件上传</span></span><br><span class="line">$ curl -X POST http://localhost:8080/upload \</span><br><span class="line"> -F <span class="string">"file=@/Users/appleboy/test.zip"</span> \</span><br><span class="line"> -H <span class="string">"Content-Type: multipart/form-data"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 多文件上传</span></span><br><span class="line">$ curl -X POST http://localhost:8080/uploads \</span><br><span class="line"> -F <span class="string">"upload[]=@/Users/appleboy/test1.zip"</span> \</span><br><span class="line"> -F <span class="string">"upload[]=@/Users/appleboy/test2.zip"</span> \</span><br><span class="line"> -H <span class="string">"Content-Type: multipart/form-data"</span></span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> gin </category>
</categories>
<tags>
<tag> go </tag>
<tag> golang </tag>
<tag> gin </tag>
</tags>
</entry>
<entry>
<title>gin blog</title>
<link href="/2019/06/06/golang/gin-blog_/"/>
<url>/2019/06/06/golang/gin-blog_/</url>
<content type="html"><![CDATA[<ul><li><a href="#安装go">安装go</a></li><li><a href="#初始工作区">初始工作区</a></li><li><a href="#初始化项目目录">初始化项目目录</a></li><li><a href="#创建数据库">创建数据库</a></li><li><a href="#编写项目配置包">编写项目配置包</a></li><li><a href="#编写api错误码包">编写API错误码包</a></li><li><a href="#编写工具包">编写工具包</a></li></ul><h2 id="安装go"><a href="#安装go" class="headerlink" title="安装go"></a>安装go</h2><p>参考:go 1.03 环境搭建</p><h2 id="初始工作区"><a href="#初始工作区" class="headerlink" title="初始工作区"></a>初始工作区</h2><figure class="highlight plain"><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">#安装govendor</span><br><span class="line">go get -u github.com/kardianos/govendor</span><br><span class="line">tree $GOPATH</span><br></pre></td></tr></table></figure><p>查看GOPATH目录<br><figure class="highlight plain"><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">$GOPATH</span><br><span class="line">├── bin</span><br><span class="line">│ └── govendor</span><br><span class="line">├── src</span><br><span class="line">│ └── github.com</span><br><span class="line">│ └── kardianos</span><br><span class="line">│ └── govendor</span><br><span class="line">│ ├── appveyor.yml</span><br><span class="line">│ ├...</span><br></pre></td></tr></table></figure></p><p>安装gin</p><figure class="highlight plain"><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">go get -u github.com/gin-gonic/gin</span><br><span class="line">tree $GOPATH</span><br></pre></td></tr></table></figure><p>再次查看GOPATH目录<br><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">$GOPATH</span><br><span class="line">├── bin</span><br><span class="line">│ └── govendor</span><br><span class="line">├── src</span><br><span class="line">│ ├── github.com</span><br><span class="line">│ │ ├── gin-contrib</span><br><span class="line">│ │ │ └── sse</span><br><span class="line">│ │ ├── gin-gonic</span><br><span class="line">│ │ │ └── gin</span><br><span class="line">│ │ ├── golang</span><br><span class="line">│ │ ├── kardianos</span><br><span class="line">│ │ │ └── govendor</span><br><span class="line">│ │ ├── mattn</span><br><span class="line">│ │ └── ugorji</span><br><span class="line">│ │ └── go</span><br><span class="line">│ ├── gopkg.in</span><br><span class="line">│ │ ├── go-playground</span><br><span class="line">│ │ │ └── validator.v8</span><br><span class="line">│ │ └── yaml.v2</span><br><span class="line">│ │ ├── apic.go</span><br></pre></td></tr></table></figure></p><h2 id="初始化项目目录"><a href="#初始化项目目录" class="headerlink" title="初始化项目目录"></a>初始化项目目录</h2><p>cat init_dir.sh<br><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">project_dir=(</span><br><span class="line">conf</span><br><span class="line">middleware</span><br><span class="line">models</span><br><span class="line">pkg</span><br><span class="line">routers</span><br><span class="line">runtime</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">pre_dir='gin-blog'</span><br><span class="line">for dir in ${project_dir[@]};</span><br><span class="line">do</span><br><span class="line">#echo $dir</span><br><span class="line">mkdir -v -p ${pre_dir}/${dir}</span><br><span class="line">done</span><br></pre></td></tr></table></figure></p><figure class="highlight plain"><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">cd src</span><br><span class="line">bash init_dir.sh</span><br><span class="line">tree gin-blog</span><br><span class="line"></span><br><span class="line">gin-blog/</span><br><span class="line">├── conf</span><br><span class="line">├── middleware</span><br><span class="line">├── models</span><br><span class="line">├── pkg</span><br><span class="line">├── routers</span><br><span class="line">└── runtime</span><br></pre></td></tr></table></figure><p>conf:用于存储配置文件<br>middleware:应用中间件<br>models:应用数据库模型<br>pkg:第三方包<br>routers 路由逻辑处理<br>runtime 应用运行时数据</p><h2 id="创建数据库"><a href="#创建数据库" class="headerlink" title="创建数据库"></a>创建数据库</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></pre></td><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line">docker stop mysql && docker rm mysql</span><br><span class="line">docker run --restart=<span class="string">"always"</span> --name mysql -v /data/mysql_data:/var/lib/mysql -v /etc/mysql:/etc/mysql -e MYSQL_ROOT_PASSWORD=Pw123456 -p 3306:3306 -d mysql:5.7</span><br><span class="line">docker <span class="built_in">exec</span> -it mysql /bin/bash</span><br><span class="line">mysql -uroot -p</span><br></pre></td></tr></table></figure><p>创建库<br><figure class="highlight plain"><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">CREATE DATABASE IF NOT EXISTS blog default charset utf8 COLLATE utf8_general_ci;</span><br><span class="line">use blog;</span><br></pre></td></tr></table></figure></p><p>标签表<br><figure class="highlight plain"><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">CREATE TABLE `blog_tag` (</span><br><span class="line"> `id` int(10) unsigned NOT NULL AUTO_INCREMENT,</span><br><span class="line"> `name` varchar(100) DEFAULT '' COMMENT '标签名称',</span><br><span class="line"> `created_on` int(10) unsigned DEFAULT '0' COMMENT '创建时间',</span><br><span class="line"> `created_by` varchar(100) DEFAULT '' COMMENT '创建人',</span><br><span class="line"> `modified_on` int(10) unsigned DEFAULT '0' COMMENT '修改时间',</span><br><span class="line"> `modified_by` varchar(100) DEFAULT '' COMMENT '修改人',</span><br><span class="line"> `deleted_on` int(10) unsigned DEFAULT '0',</span><br><span class="line"> `state` tinyint(3) unsigned DEFAULT '1' COMMENT '状态 0为禁用、1为启用',</span><br><span class="line"> PRIMARY KEY (`id`)</span><br><span class="line">) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='文章标签管理';</span><br></pre></td></tr></table></figure></p><p>文章表<br><figure class="highlight plain"><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">CREATE TABLE `blog_article` (</span><br><span class="line"> `id` int(10) unsigned NOT NULL AUTO_INCREMENT,</span><br><span class="line"> `tag_id` int(10) unsigned DEFAULT '0' COMMENT '标签ID',</span><br><span class="line"> `title` varchar(100) DEFAULT '' COMMENT '文章标题',</span><br><span class="line"> `desc` varchar(255) DEFAULT '' COMMENT '简述',</span><br><span class="line"> `content` text,</span><br><span class="line"> `created_on` int(11) DEFAULT NULL,</span><br><span class="line"> `created_by` varchar(100) DEFAULT '' COMMENT '创建人',</span><br><span class="line"> `modified_on` int(10) unsigned DEFAULT '0' COMMENT '修改时间',</span><br><span class="line"> `modified_by` varchar(255) DEFAULT '' COMMENT '修改人',</span><br><span class="line"> `deleted_on` int(10) unsigned DEFAULT '0',</span><br><span class="line"> `state` tinyint(3) unsigned DEFAULT '1' COMMENT '状态 0为禁用1为启用',</span><br><span class="line"> PRIMARY KEY (`id`)</span><br><span class="line">) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='文章管理';</span><br></pre></td></tr></table></figure></p><p>认证表<br><figure class="highlight plain"><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">CREATE TABLE `blog_auth` (</span><br><span class="line"> `id` int(10) unsigned NOT NULL AUTO_INCREMENT,</span><br><span class="line"> `username` varchar(50) DEFAULT '' COMMENT '账号',</span><br><span class="line"> `password` varchar(50) DEFAULT '' COMMENT '密码',</span><br><span class="line"> PRIMARY KEY (`id`)</span><br><span class="line">) ENGINE=InnoDB DEFAULT CHARSET=utf8;</span><br><span class="line"></span><br><span class="line">INSERT INTO `blog`.`blog_auth` (`id`, `username`, `password`) VALUES (null, 'test', 'test123456');</span><br></pre></td></tr></table></figure></p><h2 id="编写项目配置包"><a href="#编写项目配置包" class="headerlink" title="编写项目配置包"></a>编写项目配置包</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">go get -u github.com/go-ini/ini</span><br></pre></td></tr></table></figure><p>在gin-blog的conf目录下新建app.ini文件,写入内容:<br><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">#debug or release</span><br><span class="line">RUN_MODE = debug</span><br><span class="line"></span><br><span class="line">[app]</span><br><span class="line">PAGE_SIZE = 10</span><br><span class="line">JWT_SECRET = 164ebd68</span><br><span class="line"></span><br><span class="line">[server]</span><br><span class="line">HTTP_PORT = 8000</span><br><span class="line">READ_TIMEOUT = 60</span><br><span class="line">WRITE_TIMEOUT = 60</span><br><span class="line"></span><br><span class="line">[database]</span><br><span class="line">TYPE = mysql</span><br><span class="line">USER = root</span><br><span class="line">PASSWORD = Pw123456</span><br><span class="line">#127.0.0.1:3306</span><br><span class="line">HOST = 127.0.0.1:3306</span><br><span class="line">NAME = blog</span><br><span class="line">TABLE_PREFIX = blog_</span><br></pre></td></tr></table></figure></p><p>建立调用配置的setting模块,在gin-blog的pkg目录下新建setting目录,新建setting.go文件,写入内容:<br>setting.go<br><figure class="highlight go"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> setting</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line"><span class="string">"log"</span></span><br><span class="line"><span class="string">"time"</span></span><br><span class="line"></span><br><span class="line"><span class="string">"github.com/go-ini/ini"</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> (</span><br><span class="line">Cfg *ini.File</span><br><span class="line"></span><br><span class="line">RunMode <span class="keyword">string</span></span><br><span class="line"></span><br><span class="line">HTTPPort <span class="keyword">int</span></span><br><span class="line">ReadTimeout time.Duration</span><br><span class="line">WriteTimeout time.Duration</span><br><span class="line"></span><br><span class="line">PageSize <span class="keyword">int</span></span><br><span class="line">JwtSecret <span class="keyword">string</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">init</span><span class="params">()</span></span> {</span><br><span class="line"><span class="keyword">var</span> err error</span><br><span class="line">Cfg, err = ini.Load(<span class="string">"conf/app.ini"</span>)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line">log.Fatalf(<span class="string">"Fail to parse 'conf/app.ini': %v"</span>, err)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">LoadBase()</span><br><span class="line">LoadServer()</span><br><span class="line">LoadApp()</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">LoadBase</span><span class="params">()</span></span> {</span><br><span class="line">RunMode = Cfg.Section(<span class="string">""</span>).Key(<span class="string">"RUN_MODE"</span>).MustString(<span class="string">"debug"</span>)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">LoadServer</span><span class="params">()</span></span> {</span><br><span class="line">sec, err := Cfg.GetSection(<span class="string">"server"</span>)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line">log.Fatalf(<span class="string">"Fail to get section 'server': %v"</span>, err)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">RunMode = Cfg.Section(<span class="string">""</span>).Key(<span class="string">"RUN_MODE"</span>).MustString(<span class="string">"debug"</span>)</span><br><span class="line"></span><br><span class="line">HTTPPort = sec.Key(<span class="string">"HTTP_PORT"</span>).MustInt(<span class="number">8000</span>)</span><br><span class="line">ReadTimeout = time.Duration(sec.Key(<span class="string">"READ_TIMEOUT"</span>).MustInt(<span class="number">60</span>)) * time.Second</span><br><span class="line">WriteTimeout = time.Duration(sec.Key(<span class="string">"WRITE_TIMEOUT"</span>).MustInt(<span class="number">60</span>)) * time.Second</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">LoadApp</span><span class="params">()</span></span> {</span><br><span class="line">sec, err := Cfg.GetSection(<span class="string">"app"</span>)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line">log.Fatalf(<span class="string">"Fail to get section 'app': %v"</span>, err)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">JwtSecret = sec.Key(<span class="string">"JWT_SECRET"</span>).MustString(<span class="string">"!@)*#)!@U#@*!@!)"</span>)</span><br><span class="line">PageSize = sec.Key(<span class="string">"PAGE_SIZE"</span>).MustInt(<span class="number">10</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><p>当前目录结构<br><figure class="highlight plain"><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">../gin-blog/</span><br><span class="line">├── conf</span><br><span class="line">│ └── app.ini</span><br><span class="line">├── middleware</span><br><span class="line">├── models</span><br><span class="line">├── pkg</span><br><span class="line">│ └── setting</span><br><span class="line">│ └── setting.go</span><br><span class="line">├── routers</span><br><span class="line">└── runtime</span><br></pre></td></tr></table></figure></p><h2 id="编写API错误码包"><a href="#编写API错误码包" class="headerlink" title="编写API错误码包"></a>编写API错误码包</h2><p>建立错误码的e模块,在gin-blog的pkg目录下新建e目录,新建code.go和msg.go文件,写入内容:<br> code.go:<br><figure class="highlight go"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> e</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> (</span><br><span class="line">SUCCESS = <span class="number">200</span></span><br><span class="line">ERROR = <span class="number">500</span></span><br><span class="line">INVALID_PARAMS = <span class="number">400</span></span><br><span class="line"></span><br><span class="line">ERROR_EXIST_TAG = <span class="number">10001</span></span><br><span class="line">ERROR_NOT_EXIST_TAG = <span class="number">10002</span></span><br><span class="line">ERROR_NOT_EXIST_ARTICLE = <span class="number">10003</span></span><br><span class="line"></span><br><span class="line">ERROR_AUTH_CHECK_TOKEN_FAIL = <span class="number">20001</span></span><br><span class="line">ERROR_AUTH_CHECK_TOKEN_TIMEOUT = <span class="number">20002</span></span><br><span class="line">ERROR_AUTH_TOKEN = <span class="number">20003</span></span><br><span class="line">ERROR_AUTH = <span class="number">20004</span></span><br><span class="line">)</span><br></pre></td></tr></table></figure></p><p>msg.go:<br><figure class="highlight go"><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">package</span> e</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> MsgFlags = <span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span> {</span><br><span class="line">SUCCESS : <span class="string">"ok"</span>,</span><br><span class="line">ERROR : <span class="string">"fail"</span>,</span><br><span class="line">INVALID_PARAMS : <span class="string">"请求参数错误"</span>,</span><br><span class="line">ERROR_EXIST_TAG : <span class="string">"已存在该标签名称"</span>,</span><br><span class="line">ERROR_NOT_EXIST_TAG : <span class="string">"该标签不存在"</span>,</span><br><span class="line">ERROR_NOT_EXIST_ARTICLE : <span class="string">"该文章不存在"</span>,</span><br><span class="line">ERROR_AUTH_CHECK_TOKEN_FAIL : <span class="string">"Token鉴权失败"</span>,</span><br><span class="line">ERROR_AUTH_CHECK_TOKEN_TIMEOUT : <span class="string">"Token已超时"</span>,</span><br><span class="line">ERROR_AUTH_TOKEN : <span class="string">"Token生成失败"</span>,</span><br><span class="line">ERROR_AUTH : <span class="string">"Token错误"</span>,</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">GetMsg</span><span class="params">(code <span class="keyword">int</span>)</span> <span class="title">string</span></span> {</span><br><span class="line">msg, ok := MsgFlags[code]</span><br><span class="line"><span class="keyword">if</span> ok {</span><br><span class="line"><span class="keyword">return</span> msg</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> MsgFlags[ERROR]</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h2 id="编写工具包"><a href="#编写工具包" class="headerlink" title="编写工具包"></a>编写工具包</h2><p>在gin-blog的pkg目录下新建util目录<br>拉取com的依赖包<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">go get -u github.com/Unknwon/com</span><br></pre></td></tr></table></figure></p>]]></content>
<categories>
<category> gin </category>
</categories>
<tags>
<tag> go </tag>
<tag> golang </tag>
<tag> go-project </tag>
<tag> gin </tag>
</tags>
</entry>
<entry>
<title>go 3.37 面向对象</title>
<link href="/2019/05/31/golang/go-4-02-%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1_/"/>
<url>/2019/05/31/golang/go-4-02-%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1_/</url>
<content type="html"><![CDATA[<ul><li><a href="#同名字段和结构体匿名字段">同名字段和结构体匿名字段</a></li><li><a href="#结构体指针类型匿名字段">结构体指针类型匿名字段</a></li><li><a href="#面向过程与面向对象的区别">面向过程与面向对象的区别</a></li><li><a href="#方法表达式">方法表达式</a></li><li><a href="#接口定义和实现">接口定义和实现</a></li><li><a href="#多态的表现">多态的表现</a></li><li><a href="#接口继承">接口继承</a></li></ul><h2 id="同名字段和结构体匿名字段"><a href="#同名字段和结构体匿名字段" class="headerlink" title="同名字段和结构体匿名字段"></a>同名字段和结构体匿名字段</h2><figure class="highlight go"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="string">"fmt"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> person <span class="keyword">struct</span> {</span><br><span class="line">name <span class="keyword">string</span></span><br><span class="line">sex <span class="keyword">byte</span></span><br><span class="line">age <span class="keyword">int</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> student <span class="keyword">struct</span> {</span><br><span class="line">person <span class="comment">//只有类型,没有变量名,是匿名字段,继承了person的成员</span></span><br><span class="line">id <span class="keyword">int</span></span><br><span class="line">name <span class="keyword">string</span></span><br><span class="line">addr <span class="keyword">string</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line"><span class="keyword">var</span> s student <span class="comment">//声明一个变量</span></span><br><span class="line"><span class="comment">// 就近原则:如果在本作用域中找到此成员,就操作此成员,如果没有找到,找到继承的字段</span></span><br><span class="line">s.name = <span class="string">"mike"</span> <span class="comment">//student name 属于同名字段,就近原则操作本作用域字段</span></span><br><span class="line">s.sex = <span class="string">'m'</span> <span class="comment">//person sex 就近原则,本作用域没有找到,操作person的字段</span></span><br><span class="line">s.age = <span class="number">18</span> <span class="comment">//person age 就近原则,本作用域没有找到,操作person的字段</span></span><br><span class="line">s.addr = <span class="string">"bj"</span> <span class="comment">//student add 就近原则,本作用域找到,操作student字段</span></span><br><span class="line">s.person.name = <span class="string">"jack"</span> <span class="comment">//person name 显式操作person字段</span></span><br><span class="line">fmt.Printf(<span class="string">"s = %+v\n"</span>, s)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="结构体指针类型匿名字段"><a href="#结构体指针类型匿名字段" class="headerlink" title="结构体指针类型匿名字段"></a>结构体指针类型匿名字段</h2><figure class="highlight go"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="string">"fmt"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> person <span class="keyword">struct</span> {</span><br><span class="line">name <span class="keyword">string</span></span><br><span class="line">sex <span class="keyword">byte</span></span><br><span class="line">age <span class="keyword">int</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> student <span class="keyword">struct</span> {</span><br><span class="line">*person <span class="comment">//指针类型</span></span><br><span class="line">id <span class="keyword">int</span></span><br><span class="line">addr <span class="keyword">string</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line"><span class="comment">//直接使用取地址初始化指针类型</span></span><br><span class="line">s1 := student{&person{<span class="string">"mike"</span>, <span class="string">'m'</span>, <span class="number">18</span>}, <span class="number">666</span>, <span class="string">"bj"</span>}</span><br><span class="line">fmt.Println(s1.name, s1.sex, s1.age, s1.id, s1.addr)</span><br><span class="line"><span class="comment">//方法二:先定义变量</span></span><br><span class="line"><span class="keyword">var</span> s student</span><br><span class="line">s.person = <span class="built_in">new</span>(person) <span class="comment">// 分配空间</span></span><br><span class="line">s.name = <span class="string">"yoyo"</span></span><br><span class="line">s.sex = <span class="string">'f'</span></span><br><span class="line">s.age = <span class="number">19</span></span><br><span class="line">s.addr = <span class="string">"sz"</span></span><br><span class="line">fmt.Println(s.name, s.sex, s.age, s.id, s.addr)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="面向过程与面向对象的区别"><a href="#面向过程与面向对象的区别" class="headerlink" title="面向过程与面向对象的区别"></a>面向过程与面向对象的区别</h2><figure class="highlight go"><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="comment">// 面向过程,实现2个数相加</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Add01</span><span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> {</span><br><span class="line"><span class="keyword">return</span> a + b</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> v <span class="keyword">int</span> <span class="comment">// 面向对象,方法:给某个类型绑定一个函数</span></span><br><span class="line"><span class="comment">// 面向对象,把两个象相加</span></span><br><span class="line"><span class="comment">// tmp为接收者,another为形参名,代表另一个对象,最后一个v代表反回值(对象)类型,</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(tmp v)</span> <span class="title">Add02</span><span class="params">(another v)</span> <span class="title">v</span></span> {</span><br><span class="line"><span class="keyword">return</span> tmp + another</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line"><span class="keyword">var</span> result <span class="keyword">int</span></span><br><span class="line">a := <span class="number">10</span></span><br><span class="line">b := <span class="number">20</span></span><br><span class="line">result = Add01(a, b)</span><br><span class="line">fmt.Println(<span class="string">"result = "</span>, result)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> obj v = <span class="number">10</span></span><br><span class="line">r := obj.Add02(<span class="number">100</span>)</span><br><span class="line">fmt.Println(<span class="string">"obj result = "</span>, r)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="方法表达式"><a href="#方法表达式" class="headerlink" title="方法表达式"></a>方法表达式</h2><figure class="highlight go"><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 class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="string">"fmt"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> person <span class="keyword">struct</span> {</span><br><span class="line">name <span class="keyword">string</span></span><br><span class="line">sex <span class="keyword">byte</span></span><br><span class="line">age <span class="keyword">int</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(p person)</span> <span class="title">setInfoValue</span><span class="params">()</span></span> {</span><br><span class="line">fmt.Printf(<span class="string">"setInfoValue:%p ,%v\n"</span>, &p, p)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(p *person)</span> <span class="title">setInfoPointer</span><span class="params">()</span></span> {</span><br><span class="line">fmt.Printf(<span class="string">"setInfoPointer:%p ,%v\n"</span>, p, p)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">p := person{<span class="string">"mike"</span>, <span class="string">'m'</span>, <span class="number">18</span>}</span><br><span class="line">f1 := p.setInfoPointer <span class="comment">//方法值</span></span><br><span class="line">f1() <span class="comment">// 隐藏接收者</span></span><br><span class="line"></span><br><span class="line">f2 := (person).setInfoValue <span class="comment">// 方法表达式</span></span><br><span class="line">f2(p) <span class="comment">//显示把接受者传递进去</span></span><br><span class="line"></span><br><span class="line">f3 := (*person).setInfoPointer</span><br><span class="line">f3(&p) <span class="comment">//显示把接受者传递进去</span></span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="接口定义和实现"><a href="#接口定义和实现" class="headerlink" title="接口定义和实现"></a>接口定义和实现</h2><figure class="highlight go"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> Human <span class="keyword">interface</span> {</span><br><span class="line"><span class="comment">// 方法,只有声明,没有实现,由别的类型(自定义类型)实现</span></span><br><span class="line">sayhi()</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> Student <span class="keyword">struct</span> {</span><br><span class="line">name <span class="keyword">string</span></span><br><span class="line">id <span class="keyword">int</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// Student实现了此方法</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(tmp *Student)</span> <span class="title">sayhi</span><span class="params">()</span></span> {</span><br><span class="line">fmt.Printf(<span class="string">"Student [%s,%d] sayhi\n"</span>, tmp.name, tmp.id)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> Teacher <span class="keyword">struct</span> {</span><br><span class="line">addr <span class="keyword">string</span></span><br><span class="line">group <span class="keyword">string</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// Teacher实现了此方法</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(tmp *Teacher)</span> <span class="title">sayhi</span><span class="params">()</span></span> {</span><br><span class="line">fmt.Printf(<span class="string">"Teacher [%s,%s] sayhi\n"</span>, tmp.addr, tmp.group)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> MyStr <span class="keyword">string</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Mystr实现了此方法</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(tmp *MyStr)</span> <span class="title">sayhi</span><span class="params">()</span></span> {</span><br><span class="line">fmt.Printf(<span class="string">"MyStr [%s] sayhi\n"</span>, *tmp)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line"><span class="comment">// 定义接口类型的变量</span></span><br><span class="line"><span class="keyword">var</span> i Human</span><br><span class="line">s := Student{<span class="string">"mike"</span>, <span class="number">666</span>}</span><br><span class="line">i = &s <span class="comment">// 只要是实现了此接口方法的类型,那么这个类型的变量(接收者类型)就可以给接口实例赋值</span></span><br><span class="line">i.sayhi()</span><br><span class="line"></span><br><span class="line">t := &Teacher{<span class="string">"bj"</span>,<span class="string">"go"</span>}</span><br><span class="line">i = t</span><br><span class="line">i.sayhi()</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> str MyStr = <span class="string">"HELLO STR"</span></span><br><span class="line">i = &str</span><br><span class="line">i.sayhi()</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="多态的表现"><a href="#多态的表现" class="headerlink" title="多态的表现"></a>多态的表现</h2><figure class="highlight go"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="string">"fmt"</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">whoSayHi</span><span class="params">(i Human)</span></span> {</span><br><span class="line">i.sayhi()</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> Human <span class="keyword">interface</span> {</span><br><span class="line"><span class="comment">// 方法,只有声明,没有实现,由别的类型(自定义类型)实现</span></span><br><span class="line">sayhi()</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> Student <span class="keyword">struct</span> {</span><br><span class="line">name <span class="keyword">string</span></span><br><span class="line">id <span class="keyword">int</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// Student实现了此方法</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(tmp *Student)</span> <span class="title">sayhi</span><span class="params">()</span></span> {</span><br><span class="line">fmt.Printf(<span class="string">"Student [%s,%d] sayhi\n"</span>, tmp.name, tmp.id)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> Teacher <span class="keyword">struct</span> {</span><br><span class="line">addr <span class="keyword">string</span></span><br><span class="line">group <span class="keyword">string</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// Teacher实现了此方法</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(tmp *Teacher)</span> <span class="title">sayhi</span><span class="params">()</span></span> {</span><br><span class="line">fmt.Printf(<span class="string">"Teacher [%s,%s] sayhi\n"</span>, tmp.addr, tmp.group)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> MyStr <span class="keyword">string</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Mystr实现了此方法</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(tmp *MyStr)</span> <span class="title">sayhi</span><span class="params">()</span></span> {</span><br><span class="line">fmt.Printf(<span class="string">"MyStr [%s] sayhi\n"</span>, *tmp)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">s := &Student{<span class="string">"mike"</span>, <span class="number">666</span>}</span><br><span class="line">t := &Teacher{<span class="string">"bj"</span>, <span class="string">"go"</span>}</span><br><span class="line"><span class="keyword">var</span> str MyStr = <span class="string">"HELLO STR"</span></span><br><span class="line"><span class="comment">//调用同一个函数,不同的表现,多态(polymorphic),多种形态</span></span><br><span class="line">whoSayHi(s)</span><br><span class="line">whoSayHi(t)</span><br><span class="line">whoSayHi(&str)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建一个切片</span></span><br><span class="line">x := <span class="built_in">make</span>([]Human, <span class="number">3</span>)</span><br><span class="line">x[<span class="number">0</span>] = s</span><br><span class="line">x[<span class="number">0</span>] = t</span><br><span class="line">x[<span class="number">0</span>] = &str</span><br><span class="line"><span class="comment">//第一个返回下标,第二个返回下标所对应的值</span></span><br><span class="line"><span class="keyword">for</span> _, i := <span class="keyword">range</span> x {</span><br><span class="line">i.sayhi()</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="接口继承"><a href="#接口继承" class="headerlink" title="接口继承"></a>接口继承</h2><p>4.22<br><figure class="highlight go"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> Human <span class="keyword">interface</span> {</span><br><span class="line"><span class="comment">// 方法,只有声明,没有实现,由别的类型(自定义类型)实现</span></span><br><span class="line">sayhi()</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> Person <span class="keyword">interface</span> {</span><br><span class="line"><span class="comment">//Human // 匿名字段,继承了sayhi()</span></span><br><span class="line">sing(lrc <span class="keyword">string</span>)</span><br><span class="line">}</span><br><span class="line"><span class="keyword">type</span> Student <span class="keyword">struct</span> {</span><br><span class="line">name <span class="keyword">string</span></span><br><span class="line">id <span class="keyword">int</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// Student实现了sayhi方法</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(tmp *Student)</span> <span class="title">sayhi</span><span class="params">()</span></span> {</span><br><span class="line">fmt.Printf(<span class="string">"Student [%s,%d] sayhi\n"</span>, tmp.name, tmp.id)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// Student实现了sing方法</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(tmp *Student)</span> <span class="title">sing</span><span class="params">(lrc <span class="keyword">string</span>)</span></span> {</span><br><span class="line">fmt.Printf(<span class="string">"Student [%s,%d] sing %s\n"</span>, tmp.name, tmp.id, lrc)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line"><span class="keyword">var</span> i Person</span><br><span class="line"></span><br><span class="line">s := &Student{<span class="string">"mike"</span>, <span class="number">666</span>} <span class="comment">// Student实现了sayhi方法,那么s就可以给接口实例i赋值</span></span><br><span class="line">i = s</span><br><span class="line">i.sayhi() <span class="comment">// 继承来的方法</span></span><br><span class="line">i.sing(<span class="string">"学生歌..."</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>]]></content>
<categories>
<category> golang </category>
</categories>
<tags>
<tag> go </tag>
<tag> golang </tag>
</tags>
</entry>
<entry>
<title>go 3.37 struct</title>
<link href="/2019/05/31/golang/go-3-37-struct_/"/>
<url>/2019/05/31/golang/go-3-37-struct_/</url>
<content type="html"><![CDATA[<ul><li><a href="#struct普通变量初始化">struct普通变量初始化</a></li><li><a href="#struct指针变量初始化">struct指针变量初始化</a></li><li><a href="#结构体成员的使用指针变量">结构体成员的使用:指针变量</a></li><li><a href="#结构体比较和赋值">结构体比较和赋值</a></li><li><a href="#结构体做函数参数值传递">结构体做函数参数:值传递</a></li><li><a href="#结构体做函数参数地址传递">结构体做函数参数:地址传递</a></li></ul><h2 id="struct普通变量初始化"><a href="#struct普通变量初始化" class="headerlink" title="struct普通变量初始化"></a>struct普通变量初始化</h2><figure class="highlight go"><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><br><span class="line"><span class="comment">// 定义一个结构体类型</span></span><br><span class="line"><span class="keyword">type</span> student <span class="keyword">struct</span> {</span><br><span class="line">id <span class="keyword">int</span></span><br><span class="line">name <span class="keyword">string</span></span><br><span class="line">sex <span class="keyword">byte</span></span><br><span class="line">age <span class="keyword">int</span></span><br><span class="line">addr <span class="keyword">string</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="comment">// 顺序初始化结构体,每个成员必须初始化</span></span><br><span class="line"><span class="keyword">var</span> s1 student = student{<span class="number">1</span>, <span class="string">"mike"</span>, <span class="string">'m'</span>, <span class="number">18</span>, <span class="string">"bj"</span>}</span><br><span class="line">fmt.Println(<span class="string">"s1 = "</span>, s1)</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 指定成员初始化,没有初始化的成员,自动赋值为0</span></span><br><span class="line">s2 := student{name: <span class="string">"mike"</span>, addr: <span class="string">"bj"</span>}</span><br><span class="line">fmt.Println(<span class="string">"s2 = "</span>, s2)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="struct指针变量初始化"><a href="#struct指针变量初始化" class="headerlink" title="struct指针变量初始化"></a>struct指针变量初始化</h2><figure class="highlight go"><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="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line"><span class="comment">// 顺序初始化结构体,每个成员必须初始化,别忘了&</span></span><br><span class="line"><span class="keyword">var</span> p1 *student = &student{<span class="number">1</span>, <span class="string">"mike"</span>, <span class="string">'m'</span>, <span class="number">18</span>, <span class="string">"bj"</span>}</span><br><span class="line">fmt.Println(<span class="string">"p1 = "</span>, p1)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 指定成员初始化,没有初始化的成员,自动赋值为0</span></span><br><span class="line">p2 := &student{name: <span class="string">"mike"</span>, addr: <span class="string">"bj"</span>}</span><br><span class="line">fmt.Println(<span class="string">"p2 = "</span>, p2)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="结构体成员的使用-指针变量"><a href="#结构体成员的使用-指针变量" class="headerlink" title="结构体成员的使用:指针变量"></a>结构体成员的使用:指针变量</h2><figure class="highlight go"><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">type</span> student <span class="keyword">struct</span> m{</span><br><span class="line">id intm</span><br><span class="line">name <span class="keyword">string</span></span><br><span class="line">sex <span class="keyword">byte</span></span><br><span class="line">age <span class="keyword">int</span></span><br><span class="line">addr <span class="keyword">string</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></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 class="keyword">var</span> s student</span><br><span class="line"><span class="comment">// 定义一个指针变量,保存s的地址</span></span><br><span class="line"><span class="keyword">var</span> p1 *student</span><br><span class="line">p1 = &s</span><br><span class="line"><span class="comment">// 能过指针操作成员,p1.id和(*p1).id完全等价,只能使用.运算</span></span><br><span class="line">p1.id = <span class="number">1</span></span><br><span class="line">(*p1).name = <span class="string">"mike"</span></span><br><span class="line">p1.sex = <span class="string">'m'</span></span><br><span class="line">p1.age = <span class="number">18</span></span><br><span class="line">p1.addr = <span class="string">"bj"</span></span><br><span class="line">fmt.Println(<span class="string">"p1 = "</span>, p1)</span><br><span class="line">fmt.Println(<span class="string">"s.id = "</span>, s.id) <span class="comment">// 普通变量操作</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 通过new申请一个结构体</span></span><br><span class="line">p2 := <span class="built_in">new</span>(student)</span><br><span class="line">p2.id = <span class="number">2</span></span><br><span class="line">p2.name = <span class="string">"Penny"</span></span><br><span class="line">p2.sex = <span class="string">'f'</span></span><br><span class="line">p2.age = <span class="number">19</span></span><br><span class="line">p2.addr = <span class="string">"bj"</span></span><br><span class="line">fmt.Println(<span class="string">"p2 = "</span>, p2)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>打印结果:</p><figure class="highlight plain"><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">p1 = &{1 mike 109 18 bj}</span><br><span class="line">s.id = 1</span><br><span class="line">p2 = &{2 Penny 102 19 bj}</span><br></pre></td></tr></table></figure><h2 id="结构体比较和赋值"><a href="#结构体比较和赋值" class="headerlink" title="结构体比较和赋值"></a>结构体比较和赋值</h2><p>比较:<br>如果结构体的所有成员都是可以比较的,那么结构体也是可以比较的,<br>那么两个结构体将可以使用==或!=运算符进行比较,但不支持 < 或 > 。</p><p>赋值:<br>同类型的两个结构体变量可以相互赋值</p><figure class="highlight go"><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="comment">// 定义一个结构体类型</span></span><br><span class="line"><span class="keyword">type</span> student <span class="keyword">struct</span> {</span><br><span class="line">id <span class="keyword">int</span></span><br><span class="line">name <span class="keyword">string</span></span><br><span class="line">sex <span class="keyword">byte</span></span><br><span class="line">age <span class="keyword">int</span></span><br><span class="line">addr <span class="keyword">string</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">s1 := student{<span class="number">1</span>, <span class="string">"mike"</span>, <span class="string">'m'</span>, <span class="number">18</span>, <span class="string">"sz"</span>}</span><br><span class="line">s2 := student{<span class="number">1</span>, <span class="string">"mike"</span>, <span class="string">'m'</span>, <span class="number">18</span>, <span class="string">"sz"</span>}</span><br><span class="line"> fmt.Println(<span class="string">"s1 == s2"</span>, s1 == s2)</span><br><span class="line"> fmt.Println(<span class="string">"s1 != s2"</span>, s1 != s2)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">var</span> tmp student</span><br><span class="line"> tmp = s2</span><br><span class="line"> fmt.Println(<span class="string">"tmp = "</span>, tmp)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="结构体做函数参数:值传递"><a href="#结构体做函数参数:值传递" class="headerlink" title="结构体做函数参数:值传递"></a>结构体做函数参数:值传递</h2><p>值传递,形参无法改变实参</p><figure class="highlight go"><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="comment">// 定义一个结构体类型</span></span><br><span class="line"><span class="keyword">type</span> student <span class="keyword">struct</span> {</span><br><span class="line">id <span class="keyword">int</span></span><br><span class="line">name <span class="keyword">string</span></span><br><span class="line">sex <span class="keyword">byte</span></span><br><span class="line">age <span class="keyword">int</span></span><br><span class="line">addr <span class="keyword">string</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">test01</span><span class="params">(s student)</span></span> { <span class="comment">//值传递,形参无法改变实参</span></span><br><span class="line">s.id = <span class="number">666</span></span><br><span class="line">fmt.Println(<span class="string">"test01: s = "</span>, s)</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">s := student{<span class="number">1</span>, <span class="string">"mike"</span>, <span class="string">'m'</span>, <span class="number">18</span>, <span class="string">"sz"</span>}</span><br><span class="line">test01(s)</span><br><span class="line">fmt.Println(<span class="string">"main:s ="</span>, s)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="结构体做函数参数:地址传递"><a href="#结构体做函数参数:地址传递" class="headerlink" title="结构体做函数参数:地址传递"></a>结构体做函数参数:地址传递</h2><figure class="highlight go"><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="function"><span class="keyword">func</span> <span class="title">test02</span><span class="params">(s *student)</span></span> { <span class="comment">//地址传递(引用传递),形参可以改变实参</span></span><br><span class="line">s.id = <span class="number">666</span></span><br><span class="line">fmt.Println(<span class="string">"test02: s = "</span>, s)</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">s := student{<span class="number">1</span>, <span class="string">"mike"</span>, <span class="string">'m'</span>, <span class="number">18</span>, <span class="string">"sz"</span>}</span><br><span class="line">test01(&s)</span><br><span class="line">fmt.Println(<span class="string">"main:s ="</span>, s)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> golang </category>
</categories>
<tags>
<tag> go </tag>
<tag> golang </tag>
</tags>
</entry>
<entry>
<title>go project 家庭财务收支记录</title>
<link href="/2019/05/26/golang/go-project-%E5%AE%B6%E5%BA%AD%E8%B4%A2%E5%8A%A1%E6%94%B6%E6%94%AF%E8%AE%B0%E5%BD%95_/"/>
<url>/2019/05/26/golang/go-project-%E5%AE%B6%E5%BA%AD%E8%B4%A2%E5%8A%A1%E6%94%B6%E6%94%AF%E8%AE%B0%E5%BD%95_/</url>
<content type="html"><![CDATA[<ul><li><a href="#面向过程的方式编写">面向过程的方式编写</a></li><li><a href="#面向对象的方式编写">面向对象的方式编写</a></li></ul><h2 id="面向过程的方式编写"><a href="#面向过程的方式编写" class="headerlink" title="面向过程的方式编写"></a>面向过程的方式编写</h2><figure class="highlight plain"><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><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br></pre></td><td class="code"><pre><span class="line">package main</span><br><span class="line"></span><br><span class="line">import (</span><br><span class="line">"fmt"</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line">var choice string // 用户输入</span><br><span class="line">loop := true // 控制是否退出for循环</span><br><span class="line">flag := false // 当有收支行为是,置为true</span><br><span class="line">var money float64 // 发生收支行为的金额</span><br><span class="line">var note string // 发生收支行为的说明</span><br><span class="line">var balance float64 // 余额</span><br><span class="line">detail := "收支\t收支金额\t帐户余额\t说明" // 记录所有收支明细</span><br><span class="line"></span><br><span class="line">for {</span><br><span class="line"></span><br><span class="line">fmt.Println("\n--------------家庭收支记帐软件--------------")</span><br><span class="line">fmt.Println("1-收支明细")</span><br><span class="line">fmt.Println("2-登记收入")</span><br><span class="line">fmt.Println("3-登记支出")</span><br><span class="line">fmt.Println("4-退出程序")</span><br><span class="line">fmt.Println("请选择(1-4):")</span><br><span class="line">fmt.Scan(&choice)</span><br><span class="line">switch choice {</span><br><span class="line">case "1":</span><br><span class="line">fmt.Println("\n--------------当前收支明细记录--------------")</span><br><span class="line">if flag {</span><br><span class="line">fmt.Printf(detail)</span><br><span class="line">} else {</span><br><span class="line">fmt.Println("还没有收支明细,来一笔吧")</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">case "2":</span><br><span class="line">fmt.Println("本次收入金额:")</span><br><span class="line">fmt.Scan(&money)</span><br><span class="line">fmt.Println("本次收入说明:")</span><br><span class="line">fmt.Scan(&note)</span><br><span class="line">balance += money</span><br><span class="line">detail += fmt.Sprintf("\n收入\t%v\t%v\t%v", money, balance, note)</span><br><span class="line">flag = true</span><br><span class="line">case "3":</span><br><span class="line">fmt.Println("本次支出金额:")</span><br><span class="line">fmt.Scan(&money)</span><br><span class="line">if money <= balance {</span><br><span class="line">balance -= money</span><br><span class="line">fmt.Println("本次支出说明:")</span><br><span class="line">fmt.Scan(&note)</span><br><span class="line">detail += fmt.Sprintf("\n支出\t%v\t%v\t%v", money, balance, note)</span><br><span class="line">flag = true</span><br><span class="line">} else {</span><br><span class="line">fmt.Println("您的余额不足,不能完成此笔支出")</span><br><span class="line">}</span><br><span class="line">case "4":</span><br><span class="line">for {</span><br><span class="line">fmt.Println("确定退出系统吗y/n?")</span><br><span class="line">fmt.Scan(&choice)</span><br><span class="line">if choice == "y" || choice == "n" {</span><br><span class="line">break</span><br><span class="line">}</span><br><span class="line">fmt.Println("您的输入有误")</span><br><span class="line">}</span><br><span class="line">if choice == "y" {</span><br><span class="line">loop = false</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">default:</span><br><span class="line">fmt.Println("输入不正确,请输入正确选项")</span><br><span class="line">}</span><br><span class="line">if loop == false {</span><br><span class="line">fmt.Printf("感谢您使用家庭收支记账软件")</span><br><span class="line">break</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="面向对象的方式编写"><a href="#面向对象的方式编写" class="headerlink" title="面向对象的方式编写"></a>面向对象的方式编写</h2><p><strong>目录结构:</strong><br><figure class="highlight plain"><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">family_account/</span><br><span class="line">├── main.go</span><br><span class="line">└── util</span><br><span class="line"> └── family_account.go</span><br></pre></td></tr></table></figure></p><p><strong>util/family_account.go</strong></p><figure class="highlight plain"><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><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br></pre></td><td class="code"><pre><span class="line">package util</span><br><span class="line"></span><br><span class="line">import (</span><br><span class="line">"fmt"</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">type familyAccount struct {</span><br><span class="line">choice string // 用户输入</span><br><span class="line">loop bool // 控制是否退出for循环</span><br><span class="line">flag bool // 当有收支行为是,置为true</span><br><span class="line">money float64 // 发生收支行为的金额</span><br><span class="line">note string // 发生收支行为的说明</span><br><span class="line">balance float64 // 余额</span><br><span class="line">detail string</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">func NewFamilyAccount() *familyAccount {</span><br><span class="line">return &familyAccount{</span><br><span class="line">choice: "", // 用户输入</span><br><span class="line">loop: true, // 控制是否退出for循环</span><br><span class="line">flag: false, // 当有收支行为是,置为true</span><br><span class="line">money: 0.0, // 发生收支行为的金额</span><br><span class="line">note: "", // 发生收支行为的说明</span><br><span class="line">balance: 0.0, // 余额</span><br><span class="line">detail: "收支\t收支金额\t帐户余额\t说明", // 记录所有收支明细</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">func (this *familyAccount) showdetails() {</span><br><span class="line">fmt.Println("\n--------------当前收支明细记录--------------")</span><br><span class="line">if this.flag {</span><br><span class="line">fmt.Printf(this.detail)</span><br><span class="line">} else {</span><br><span class="line">fmt.Println("还没有收支明细,来一笔吧")</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">func (this *familyAccount) income() {</span><br><span class="line">fmt.Println("本次收入金额:")</span><br><span class="line">fmt.Scan(&this.money)</span><br><span class="line">fmt.Println("本次收入说明:")</span><br><span class="line">fmt.Scan(&this.note)</span><br><span class="line">this.balance += this.money</span><br><span class="line">this.detail += fmt.Sprintf("\n收入\t%v\t%v\t%v", this.money, this.balance, this.note)</span><br><span class="line">this.flag = true</span><br><span class="line">}</span><br><span class="line">func (this *familyAccount) pay() {</span><br><span class="line">fmt.Println("本次支出金额:")</span><br><span class="line">fmt.Scan(&this.money)</span><br><span class="line">if this.money <= this.balance {</span><br><span class="line">this.balance -= this.money</span><br><span class="line">fmt.Println("本次支出说明:")</span><br><span class="line">fmt.Scan(&this.note)</span><br><span class="line">this.detail += fmt.Sprintf("\n支出\t%v\t%v\t%v", this.money, this.balance, this.note)</span><br><span class="line">this.flag = true</span><br><span class="line">} else {</span><br><span class="line">fmt.Println("您的余额不足,不能完成此笔支出")</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">func (this *familyAccount) exit() {</span><br><span class="line">for {</span><br><span class="line">fmt.Println("确定退出系统吗y/n?")</span><br><span class="line">fmt.Scan(&this.choice)</span><br><span class="line">if this.choice == "y" || this.choice == "n" {</span><br><span class="line">break</span><br><span class="line">}</span><br><span class="line">fmt.Println("您的输入有误")</span><br><span class="line">}</span><br><span class="line">if this.choice == "y" {</span><br><span class="line">this.loop = false</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line">func (this *familyAccount) MainMenu() {</span><br><span class="line">for {</span><br><span class="line">fmt.Println("\n--------------家庭收支记帐软件--------------")</span><br><span class="line">fmt.Println("1-收支明细")</span><br><span class="line">fmt.Println("2-登记收入")</span><br><span class="line">fmt.Println("3-登记支出")</span><br><span class="line">fmt.Println("4-退出程序")</span><br><span class="line">fmt.Println("请选择(1-4):")</span><br><span class="line">fmt.Scan(&this.choice)</span><br><span class="line">switch this.choice {</span><br><span class="line">case "1":</span><br><span class="line">this.showdetails()</span><br><span class="line">case "2":</span><br><span class="line">this.income()</span><br><span class="line">case "3":</span><br><span class="line">this.pay()</span><br><span class="line">case "4":</span><br><span class="line">this.exit()</span><br><span class="line">default:</span><br><span class="line">fmt.Println("输入不正确,请输入正确选项")</span><br><span class="line">}</span><br><span class="line">if this.loop == false {</span><br><span class="line">fmt.Printf("感谢您使用家庭收支记账软件")</span><br><span class="line">break</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><p><strong>main.go</strong><br><figure class="highlight plain"><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">package main</span><br><span class="line"></span><br><span class="line">import (</span><br><span class="line"> "family_account/util"</span><br><span class="line"></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line">util.NewFamilyAccount().MainMenu()</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>]]></content>
<categories>
<category> golang </category>
</categories>
<tags>
<tag> go </tag>
<tag> golang </tag>
<tag> go-project </tag>
</tags>
</entry>
<entry>
<title>go 3.31 map</title>
<link href="/2019/05/25/golang/go-3-31-map_/"/>
<url>/2019/05/25/golang/go-3-31-map_/</url>
<content type="html"><![CDATA[<ul><li><a href="#map的基本使用">map的基本使用</a></li><li><a href="#map遍列">map遍列</a></li><li><a href="#delete删除key">delete删除key</a></li><li><a href="#map作函数参数">map作函数参数</a></li></ul><h2 id="map的基本使用"><a href="#map的基本使用" class="headerlink" title="map的基本使用"></a>map的基本使用</h2><figure class="highlight go"><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"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line"><span class="keyword">var</span> m1 <span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span> <span class="comment">// var声明一个map</span></span><br><span class="line">fmt.Println(<span class="string">"m1 = "</span>, m1)</span><br><span class="line">fmt.Println(<span class="string">"len(m1) = "</span>, <span class="built_in">len</span>(m1)) <span class="comment">//map只有len,没有cap</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 可以通过make创建</span></span><br><span class="line">m2 := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>)</span><br><span class="line">fmt.Println(<span class="string">"m2 = "</span>, m2)</span><br><span class="line">fmt.Println(<span class="string">"len(m2) = "</span>, <span class="built_in">len</span>(m2))</span><br><span class="line"></span><br><span class="line"><span class="comment">// 可以通过make创建,指定长度,但是一个元素也没有,长度仍然为0,相当于指定的容量</span></span><br><span class="line">m3 := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>, <span class="number">2</span>)</span><br><span class="line">m3[<span class="number">1</span>] = <span class="string">"a"</span> <span class="comment">//map操作</span></span><br><span class="line">m3[<span class="number">2</span>] = <span class="string">"a"</span></span><br><span class="line">m3[<span class="number">3</span>] = <span class="string">"a"</span></span><br><span class="line">m3[<span class="number">4</span>] = <span class="string">"a"</span></span><br><span class="line">m3[<span class="number">2</span>] = <span class="string">"b"</span> <span class="comment">// 键值是唯一的,如果键的值已经存在,再次赋值就修改,如果不存在,则增加</span></span><br><span class="line">fmt.Println(<span class="string">"m3 = "</span>, m3)</span><br><span class="line">fmt.Println(<span class="string">"len(m3) = "</span>, <span class="built_in">len</span>(m3))</span><br><span class="line"></span><br><span class="line"><span class="comment">// map初始化</span></span><br><span class="line">m4 := <span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>{<span class="number">1</span>: <span class="string">"a"</span>, <span class="number">2</span>: <span class="string">"b"</span>}</span><br><span class="line">fmt.Println(<span class="string">"m4 = "</span>, m4)</span><br><span class="line">fmt.Println(<span class="string">"len(m4) = "</span>, <span class="built_in">len</span>(m4))</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="map遍列"><a href="#map遍列" class="headerlink" title="map遍列"></a>map遍列</h2><figure class="highlight go"><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">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line"><span class="string">"fmt"</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">m := <span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>{<span class="number">1</span>: <span class="string">"aaa"</span>, <span class="number">2</span>: <span class="string">"bbb"</span>, <span class="number">3</span>: <span class="string">"ccc"</span>}</span><br><span class="line"><span class="comment">//通过range返回key,value键值对</span></span><br><span class="line"><span class="keyword">for</span> key, value := <span class="keyword">range</span> m {</span><br><span class="line">fmt.Printf(<span class="string">"%d ===> %s\n"</span>, key, value)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 如何判断一个key是否存在</span></span><br><span class="line"> <span class="comment">// 返回值value为key 0 对应的值,返回值ok为key 0是否存在的条件,返回值ok为true,表示存在</span></span><br><span class="line">value, ok := m[<span class="number">0</span>]</span><br><span class="line"><span class="keyword">if</span> ok == <span class="literal">true</span> {</span><br><span class="line">fmt.Println(<span class="string">"m[1]="</span>, value)</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line">fmt.Println(<span class="string">"m[0] not exists"</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="delete删除key"><a href="#delete删除key" class="headerlink" title="delete删除key"></a>delete删除key</h2><figure class="highlight go"><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"> m := <span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>{<span class="number">1</span>: <span class="string">"aaa"</span>, <span class="number">2</span>: <span class="string">"bbb"</span>, <span class="number">3</span>: <span class="string">"ccc"</span>}</span><br><span class="line">key := <span class="number">1</span></span><br><span class="line"><span class="built_in">delete</span>(m, key)</span><br><span class="line">fmt.Println(m)</span><br></pre></td></tr></table></figure><h2 id="map作函数参数"><a href="#map作函数参数" class="headerlink" title="map作函数参数"></a>map作函数参数</h2><p>map作函数参数时是引用传递</p><figure class="highlight go"><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="function"><span class="keyword">func</span> <span class="title">mondify_key</span><span class="params">(m <span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>)</span></span> {</span><br><span class="line"> <span class="built_in">delete</span>(m, <span class="number">2</span>)</span><br><span class="line">m[<span class="number">3</span>] = <span class="string">"ddd"</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">m := <span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">string</span>{<span class="number">1</span>: <span class="string">"aaa"</span>, <span class="number">2</span>: <span class="string">"bbb"</span>, <span class="number">3</span>: <span class="string">"ccc"</span>}</span><br><span class="line">fmt.Println(m)</span><br><span class="line">mondify_key(m) <span class="comment">// 作函数参数</span></span><br><span class="line">fmt.Println(m)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> golang </category>
</categories>
<tags>
<tag> go </tag>
<tag> golang </tag>
</tags>
</entry>
<entry>
<title>go 3.08 数组</title>
<link href="/2019/05/22/golang/go-3-08-%E6%95%B0%E7%BB%84_/"/>
<url>/2019/05/22/golang/go-3-08-%E6%95%B0%E7%BB%84_/</url>
<content type="html"><![CDATA[<ul><li><a href="#数组">数组</a></li><li><a href="#基本操作">基本操作</a></li><li><a href="#二维数组">二维数组</a></li><li><a href="#数组支持比较">数组支持比较</a></li><li><a href="#同类型且同长度的数组可以赋值">同类型且同长度的数组可以赋值</a></li><li><a href="#随机数的使用">随机数的使用</a></li><li><a href="#冒泡排序代码的实现">冒泡排序代码的实现</a></li><li><a href="#数组作函数参数">数组作函数参数</a></li><li><a href="#数组指针作函数参数">数组指针作函数参数</a></li><li><a href="#数组与切片的区别">数组与切片的区别</a></li><li><a href="#切片的创建">切片的创建</a></li><li><a href="#切片截取">切片截取</a></li><li><a href="#append函数的使用">append函数的使用</a></li><li><a href="#copy函数的使用">copy函数的使用</a></li><li><a href="#切片作函数参数">切片作函数参数</a></li><li><a href="#取出数字的每一位">取出数字的每一位</a></li></ul><h2 id="数组"><a href="#数组" class="headerlink" title="数组"></a>数组</h2><p>数组是同一个类型的数据集合</p><h2 id="基本操作"><a href="#基本操作" class="headerlink" title="基本操作"></a>基本操作</h2><p>初始化与遍列<br><figure class="highlight go"><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line"><span class="keyword">var</span> a [<span class="number">10</span>]<span class="keyword">int</span> <span class="comment">//只是声明,未初始化,未初始化的数组元素默认为0</span></span><br><span class="line">fmt.Println(<span class="string">"a = "</span>, a)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> b [<span class="number">6</span>]<span class="keyword">int</span> = [<span class="number">6</span>]<span class="keyword">int</span>{<span class="number">10</span>, <span class="number">20</span>, <span class="number">30</span>, <span class="number">40</span>} <span class="comment">// 部份初始化</span></span><br><span class="line">fmt.Println(<span class="string">"b = "</span>, b)</span><br><span class="line">c := [<span class="number">6</span>]<span class="keyword">int</span>{<span class="number">10</span>, <span class="number">20</span>, <span class="number">30</span>, <span class="number">40</span>} <span class="comment">// 部份初始化</span></span><br><span class="line">fmt.Println(<span class="string">"c = "</span>, c)</span><br><span class="line"></span><br><span class="line">d := [<span class="number">5</span>]<span class="keyword">int</span>{<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">40</span>, <span class="number">50</span>} <span class="comment">// 全部初始化</span></span><br><span class="line">fmt.Println(<span class="string">"d = "</span>, d)</span><br><span class="line"></span><br><span class="line"> e := [<span class="number">5</span>]<span class="keyword">int</span>{<span class="number">0</span>: <span class="number">100</span>, <span class="number">2</span>: <span class="string">'a'</span>, <span class="number">4</span>: <span class="number">10</span>} <span class="comment">// 指定下标为0,2,4的元素初始化</span></span><br><span class="line">fmt.Println(<span class="string">"e = "</span>, e)</span><br><span class="line"></span><br><span class="line"><span class="comment">//通过下标获取元素</span></span><br><span class="line"><span class="keyword">for</span> i := <span class="number">0</span>; i < <span class="built_in">len</span>(b); i++ {</span><br><span class="line">fmt.Printf(<span class="string">"index:b[%d] = %d\n"</span>, i, b[i])</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 通过range遍列数组</span></span><br><span class="line"><span class="keyword">for</span> i, data := <span class="keyword">range</span> b {</span><br><span class="line">fmt.Printf(<span class="string">"range:b[%d] = %d\n"</span>, i, data)</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h2 id="二维数组"><a href="#二维数组" class="headerlink" title="二维数组"></a>二维数组</h2><figure class="highlight go"><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></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 class="keyword">var</span> a [<span class="number">3</span>][<span class="number">4</span>]<span class="keyword">int</span> <span class="comment">//只是声明,未初始化,未初始化的数组元素默认为0</span></span><br><span class="line">fmt.Println(<span class="string">"a = "</span>, a)</span><br><span class="line">data := <span class="number">0</span></span><br><span class="line"><span class="keyword">for</span> i := <span class="number">0</span>; i < <span class="number">3</span>; i++ {</span><br><span class="line"><span class="keyword">for</span> j := <span class="number">0</span>; j < <span class="number">4</span>; j++ {</span><br><span class="line">data++</span><br><span class="line">a[i][j] = data</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">fmt.Println(<span class="string">"a = "</span>, a)</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 二维数组初始化部分元素</span></span><br><span class="line"> b := [<span class="number">3</span>][<span class="number">4</span>]<span class="keyword">int</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"> fmt.Println(<span class="string">"b = "</span>, b)</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 二维数组指定元素初始化</span></span><br><span class="line"> c := [<span class="number">3</span>][<span class="number">4</span>]<span class="keyword">int</span>{<span class="number">2</span>: {<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>: <span class="number">100</span>}}</span><br><span class="line"> fmt.Println(<span class="string">"c = "</span>, c)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="数组支持比较"><a href="#数组支持比较" class="headerlink" title="数组支持比较"></a>数组支持比较</h2><p>只支持:==,!=</p><h2 id="同类型且同长度的数组可以赋值"><a href="#同类型且同长度的数组可以赋值" class="headerlink" title="同类型且同长度的数组可以赋值"></a>同类型且同长度的数组可以赋值</h2><figure class="highlight go"><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">a := [<span class="number">5</span>]<span class="keyword">int</span>{<span class="number">2</span>, <span class="number">3</span>, <span class="number">3</span>}</span><br><span class="line"><span class="keyword">var</span> b [<span class="number">5</span>]<span class="keyword">int</span></span><br><span class="line">b = a</span><br><span class="line">fmt.Println(<span class="string">"b = "</span>, b)</span><br></pre></td></tr></table></figure><h2 id="随机数的使用"><a href="#随机数的使用" class="headerlink" title="随机数的使用"></a>随机数的使用</h2><figure class="highlight go"><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">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line"><span class="string">"fmt"</span></span><br><span class="line"><span class="string">"math/rand"</span></span><br><span class="line"><span class="string">"time"</span></span><br><span class="line">)</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></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 class="comment">// 所以以时间的变化设置变化的种子,以产生不同的随机数</span></span><br><span class="line">rand.Seed(time.Now().UnixNano())</span><br><span class="line"><span class="keyword">for</span> i := <span class="number">0</span>; i < <span class="number">5</span>; i++ {</span><br><span class="line">fmt.Println(<span class="string">"rand = "</span>, rand.Intn(<span class="number">100</span>)) <span class="comment">// 产生100以内的随机整数</span></span><br><span class="line">fmt.Println(<span class="string">"rand = "</span>, rand.Int()) <span class="comment">// 产生很大的随机整数</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="冒泡排序代码的实现"><a href="#冒泡排序代码的实现" class="headerlink" title="冒泡排序代码的实现"></a>冒泡排序代码的实现</h2><figure class="highlight go"><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="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">a := []<span class="keyword">int</span>{<span class="number">10</span>, <span class="number">12</span>, <span class="number">34</span>, <span class="number">330</span>, <span class="number">56</span>, <span class="number">7</span>, <span class="number">2</span>, <span class="number">23</span>}</span><br><span class="line">fmt.Println(a)</span><br><span class="line"><span class="keyword">for</span> i := <span class="number">0</span>; i < <span class="built_in">len</span>(a)<span class="number">-1</span>; i++ {</span><br><span class="line"><span class="keyword">for</span> j := <span class="number">0</span>; j < <span class="built_in">len</span>(a)-i<span class="number">-1</span>; j++ { <span class="comment">//每一轮把最大的最到放到后面</span></span><br><span class="line"><span class="keyword">if</span> a[j] > a[j+<span class="number">1</span>] {</span><br><span class="line">a[j], a[j+<span class="number">1</span>] = a[j+<span class="number">1</span>], a[j]</span><br><span class="line">fmt.Println(<span class="string">"a = "</span>, a)</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><figure class="highlight go"><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></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line"><span class="string">"fmt"</span></span><br><span class="line"><span class="string">"math/rand"</span></span><br><span class="line"><span class="string">"time"</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">rand.Seed(time.Now().UnixNano())</span><br><span class="line"><span class="keyword">var</span> a [<span class="number">10</span>]<span class="keyword">int</span></span><br><span class="line"><span class="keyword">for</span> i := <span class="number">0</span>; i < <span class="built_in">len</span>(a); i++ {</span><br><span class="line">a[i] = rand.Intn(<span class="number">100</span>)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">fmt.Println(a)</span><br><span class="line"><span class="keyword">for</span> i := <span class="number">0</span>; i < <span class="built_in">len</span>(a)<span class="number">-1</span>; i++ {</span><br><span class="line"><span class="keyword">for</span> j := i + <span class="number">1</span>; j < <span class="built_in">len</span>(a); j++ {</span><br><span class="line"><span class="keyword">if</span> a[i] < a[j] {</span><br><span class="line">a[i], a[j] = a[j], a[i]</span><br><span class="line">fmt.Println(a)</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">fmt.Println(a)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="数组作函数参数"><a href="#数组作函数参数" class="headerlink" title="数组作函数参数"></a>数组作函数参数</h2><p>数组作为函数参数,是值拷贝</p><figure class="highlight go"><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="function"><span class="keyword">func</span> <span class="title">modify</span><span class="params">(a [5]<span class="keyword">int</span>)</span></span> {</span><br><span class="line">a[<span class="number">0</span>] = <span class="number">666</span></span><br><span class="line">fmt.Println(<span class="string">"modify: a= "</span>, a)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line"><span class="keyword">var</span> a [<span class="number">5</span>]<span class="keyword">int</span> = [<span class="number">5</span>]<span class="keyword">int</span>{<span class="number">11</span>, <span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>}</span><br><span class="line">fmt.Println(<span class="string">"main:a = "</span>, a)</span><br><span class="line">modify(a)</span><br><span class="line">fmt.Println(<span class="string">"main:a = "</span>, a)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="数组指针作函数参数"><a href="#数组指针作函数参数" class="headerlink" title="数组指针作函数参数"></a>数组指针作函数参数</h2><figure class="highlight go"><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="comment">// p代表指针所指的内存地址,就是实参a</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">modify_pointer</span><span class="params">(p *[5]<span class="keyword">int</span>)</span></span> {</span><br><span class="line">(*p)[<span class="number">0</span>] = <span class="number">888</span></span><br><span class="line">fmt.Println(<span class="string">"modify_pointer: p= "</span>, *p)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a [<span class="number">5</span>]<span class="keyword">int</span> = [<span class="number">5</span>]<span class="keyword">int</span>{<span class="number">11</span>, <span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>}</span><br><span class="line">fmt.Println(<span class="string">"main:a = "</span>, a)</span><br><span class="line">modify_pointer(&a)</span><br><span class="line">fmt.Println(<span class="string">"main modify_pointer:a = "</span>, a)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="数组与切片的区别"><a href="#数组与切片的区别" class="headerlink" title="数组与切片的区别"></a>数组与切片的区别</h2><p>数组[]是是固定的一个常量,数组不能修改长度(len)和容量(cap)<br>切片[]中为空时,或者为…时,切片的长度(len)或容量(cap)可以不固定</p><figure class="highlight go"><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="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">a := [<span class="number">5</span>]<span class="keyword">int</span>{<span class="number">11</span>, <span class="number">12</span>, <span class="number">13</span>, <span class="number">14</span>}</span><br><span class="line">fmt.Printf(<span class="string">"a:len(a)=%d,cap(a)=%d\n"</span>, <span class="built_in">len</span>(a), <span class="built_in">cap</span>(a))</span><br><span class="line"></span><br><span class="line">s := []<span class="keyword">int</span>{<span class="number">23</span>, <span class="number">2</span>, <span class="number">5</span>, <span class="number">6</span>}</span><br><span class="line">fmt.Printf(<span class="string">"s:len(s)=%d,cap(s)=%d\n"</span>, <span class="built_in">len</span>(s), <span class="built_in">cap</span>(s))</span><br><span class="line"></span><br><span class="line"> <span class="comment">//给切片追加一个成员,长度自动加1,容量自动增加到原来的2倍</span></span><br><span class="line">s = <span class="built_in">append</span>(s, <span class="number">1000</span>)</span><br><span class="line">fmt.Printf(<span class="string">"s:s=%v\n"</span>, s)</span><br><span class="line">fmt.Printf(<span class="string">"s:len(s)=%d,cap(s)=%d\n"</span>, <span class="built_in">len</span>(s), <span class="built_in">cap</span>(s))</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="切片的创建"><a href="#切片的创建" class="headerlink" title="切片的创建"></a>切片的创建</h2><figure class="highlight go"><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="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="comment">// 自动推导类型,创建并初始化</span></span><br><span class="line">s1 := []<span class="keyword">int</span>{<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>}</span><br><span class="line">fmt.Println(<span class="string">"s1="</span>, s1)</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 使用make创建切片,格式:make([]类型,长度,容量)</span></span><br><span class="line">s2 := <span class="built_in">make</span>([]<span class="keyword">int</span>, <span class="number">5</span>, <span class="number">10</span>)</span><br><span class="line">fmt.Printf(<span class="string">"len=%d,cap = %d\n"</span>, <span class="built_in">len</span>(s2), <span class="built_in">cap</span>(s2))</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 没有指定容量,那么容量长度一样</span></span><br><span class="line">s3 := <span class="built_in">make</span>([]<span class="keyword">int</span>, <span class="number">5</span>)</span><br><span class="line">fmt.Printf(<span class="string">"len=%d,cap = %d\n"</span>, <span class="built_in">len</span>(s3), <span class="built_in">cap</span>(s3))</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="切片截取"><a href="#切片截取" class="headerlink" title="切片截取"></a>切片截取</h2><figure class="highlight go"><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="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">s1 := []<span class="keyword">int</span>{<span class="number">0</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">fmt.Println(<span class="string">"s[n]: s1[1] = "</span>, s1[<span class="number">1</span>]) <span class="comment">// 截取索引位置为n的成员</span></span><br><span class="line">fmt.Println(<span class="string">"s1[:]: s1[:] = "</span>, s1[:]) <span class="comment">// 从0到最后一个索引成员的截取</span></span><br><span class="line">fmt.Println(<span class="string">"s1[low:]: s1[1:] = "</span>, s1[<span class="number">1</span>:]) <span class="comment">// 从low到len(s1)-1处所获得的切片</span></span><br><span class="line">fmt.Println(<span class="string">"s1[:high]: s1[:3] = "</span>, s1[:<span class="number">3</span>]) <span class="comment">// 从0到high所获得的切片:len=high</span></span><br><span class="line">fmt.Println(<span class="string">"s1[low:high]: s1[2:4] = "</span>, s1[<span class="number">2</span>:<span class="number">4</span>]) <span class="comment">// 从low到high获取的切片:len=high-low</span></span><br><span class="line">fmt.Println(<span class="string">"s1[low:high:max]: s1[2:4:5] = "</span>, s1[<span class="number">2</span>:<span class="number">4</span>:<span class="number">5</span>]) <span class="comment">// 从low到high获取的切片:len=high-low,cap = max-low</span></span><br><span class="line"><span class="comment">// 切片长度总是 <= 切片容量: len(s) < cap(s)</span></span><br><span class="line"> <span class="comment">// 切片容量总是 >= 切片长度: cap(s) >= len(s)</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>不管切片如何操作,最终都是操作的底层数组<br><figure class="highlight go"><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="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">s := []<span class="keyword">int</span>{<span class="number">0</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">fmt.Println(<span class="string">"s = "</span>, s)</span><br><span class="line">s1 := s[<span class="number">2</span>:<span class="number">4</span>]</span><br><span class="line">fmt.Println(<span class="string">"s[2:4] = s1 = "</span>, s1)</span><br><span class="line">s1[<span class="number">0</span>] = <span class="number">666</span></span><br><span class="line">fmt.Println(<span class="string">"s1 = "</span>, s1)</span><br><span class="line">fmt.Println(<span class="string">"s = "</span>, s)</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h2 id="append函数的使用"><a href="#append函数的使用" class="headerlink" title="append函数的使用"></a>append函数的使用</h2><figure class="highlight go"><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">var</span> s [] <span class="keyword">int</span></span><br><span class="line">s = <span class="built_in">append</span>(s,<span class="number">1</span>) <span class="comment">// 追加一个元素</span></span><br><span class="line">s = <span class="built_in">append</span>(s,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>) <span class="comment">// 追加3个元素</span></span><br><span class="line"><span class="comment">// append会智能的增加底层数组的容量:一旦超过原底层数组容量,通常以2倍的容量重新分配底层数组,并复制原来的数据</span></span><br></pre></td></tr></table></figure><h2 id="copy函数的使用"><a href="#copy函数的使用" class="headerlink" title="copy函数的使用"></a>copy函数的使用</h2><figure class="highlight go"><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="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">src_slice := []<span class="keyword">int</span>{<span class="number">1</span>, <span class="number">2</span>}</span><br><span class="line">dst_slice := []<span class="keyword">int</span>{<span class="number">6</span>, <span class="number">6</span>, <span class="number">6</span>, <span class="number">6</span>, <span class="number">6</span>}</span><br><span class="line"><span class="built_in">copy</span>(dst_slice, src_slice) <span class="comment">//注意目标在前,源在后</span></span><br><span class="line">fmt.Println(dst_slice) <span class="comment">// 只是相同索引的 目标成员 被替换为 源切片成员</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="切片作函数参数"><a href="#切片作函数参数" class="headerlink" title="切片作函数参数"></a>切片作函数参数</h2><p>切片作函数参数,传递的是引用,函数中对传入的变量的修改会作用于函数之外的变量值</p><figure class="highlight go"><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="function"><span class="keyword">func</span> <span class="title">slice_args</span><span class="params">(s []<span class="keyword">int</span>)</span></span> {</span><br><span class="line">s[<span class="number">0</span>] = <span class="number">666</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">s := <span class="built_in">make</span>([]<span class="keyword">int</span>, <span class="number">1</span>)</span><br><span class="line">slice_args(s) <span class="comment">// 切片作函数参数,传递的是引用,所以值会被调用函数改变</span></span><br><span class="line">fmt.Println(s)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="取出数字的每一位"><a href="#取出数字的每一位" class="headerlink" title="取出数字的每一位"></a>取出数字的每一位</h2><figure class="highlight go"><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">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line"><span class="string">"fmt"</span></span><br><span class="line"><span class="string">"math/rand"</span></span><br><span class="line"><span class="string">"time"</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">GetNum</span><span class="params">(s []<span class="keyword">int</span>, num <span class="keyword">int</span>)</span></span> {</span><br><span class="line">s[<span class="number">0</span>] = num / <span class="number">1000</span> <span class="comment">// 取千位</span></span><br><span class="line">s[<span class="number">1</span>] = num % <span class="number">1000</span> / <span class="number">100</span> <span class="comment">// 取百位</span></span><br><span class="line">s[<span class="number">2</span>] = num % <span class="number">1000</span> % <span class="number">100</span> / <span class="number">10</span> <span class="comment">// 取百位</span></span><br><span class="line">s[<span class="number">3</span>] = num % <span class="number">1000</span> % <span class="number">100</span> % <span class="number">10</span> <span class="comment">// 取百位</span></span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">rand.Seed(time.Now().UnixNano())</span><br><span class="line">num := rand.Intn(<span class="number">1000</span>) <span class="comment">//创建一个1000以内的随机数</span></span><br><span class="line">fmt.Println(<span class="string">"main:num ="</span>, num)</span><br><span class="line">s := <span class="built_in">make</span>([]<span class="keyword">int</span>, <span class="number">4</span>) <span class="comment">//创建一个保存4个成员的切片</span></span><br><span class="line">GetNum(s, num) <span class="comment">//将切片与数字传入函数</span></span><br><span class="line">fmt.Println(<span class="string">"s="</span>, s) <span class="comment">// 得到随机数的每一位,保存到切片之中</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> golang </category>
</categories>
<tags>
<tag> go </tag>
<tag> golang </tag>
</tags>
</entry>
<entry>
<title>go 3.02 指针</title>
<link href="/2019/05/21/golang/go-3-02-%E6%8C%87%E9%92%88_/"/>
<url>/2019/05/21/golang/go-3-02-%E6%8C%87%E9%92%88_/</url>
<content type="html"><![CDATA[<ul><li><a href="#变量内存和指针地址">变量内存和指针地址</a></li><li><a href="#指针的基本使用">指针的基本使用</a></li><li><a href="#不要操作没有合法指向的内存">不要操作没有合法指向的内存</a></li><li><a href="#new函数的使用">new函数的使用</a></li><li><a href="#值传递与地址传递">值传递与地址传递</a></li></ul><h2 id="变量内存和指针地址"><a href="#变量内存和指针地址" class="headerlink" title="变量内存和指针地址"></a>变量内存和指针地址</h2><p>指针是一个代表着某个内存地址的值。这个内存地址往往是在内存中存储的另一个变量的值的起始位置。</p><figure class="highlight plain"><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">func main() {</span><br><span class="line">// 每个变量有两层含义:变量的内存, 变量的地址</span><br><span class="line">var a int = 10</span><br><span class="line">fmt.Printf("a = %d \n", a) // 变量的内存</span><br><span class="line">fmt.Printf("&a = %v \n", &a) // 取地址,取变量a的内存地址</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>打个比喻帮助理解:<br>内存 -> 想像成教室<br>&a -> 想像成教室的门牌号<br>教室 存放 桌子<br>内存存放数据: a = 10</p><h2 id="指针的基本使用"><a href="#指针的基本使用" class="headerlink" title="指针的基本使用"></a>指针的基本使用</h2><p>保存某个变量的地址,需要指针类型<br>如:*int保存int的地址,**int保存*int的地址<br>声明指针类型:</p><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">func main(){</span><br><span class="line"> var a int = 10</span><br><span class="line"> var p *int //声明p为指针类型</span><br><span class="line">p = &a</span><br><span class="line">fmt.Printf("p = %v, &a = %v \n", p, &a)</span><br><span class="line">*p = 666 // *p操作的不是p的内存,是p所指向的内存(就是a)</span><br><span class="line">fmt.Printf("*p = %v, a=%v\n", *p, a)</span><br><span class="line">var q **int // 声明一个指针的指针q</span><br><span class="line">q = &p // 把p的内存地址赋值给q</span><br><span class="line">fmt.Printf("q = %v,&p = %v\n", q, &p)</span><br><span class="line"> var b int = 20</span><br><span class="line">*q = &b // 使用*q操作p的值,即让p指向b的内存地址</span><br><span class="line">fmt.Printf("*p= %v", *p) //由于p的指向变成了b的地址,所以这里*p就变成了b的值</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="不要操作没有合法指向的内存"><a href="#不要操作没有合法指向的内存" class="headerlink" title="不要操作没有合法指向的内存"></a>不要操作没有合法指向的内存</h2><figure class="highlight plain"><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">func main() {</span><br><span class="line">// 不要操作没有合法指向的内存(空批针)</span><br><span class="line">var p *int</span><br><span class="line">p = nil</span><br><span class="line">fmt.Printf("p = %v\n", p)</span><br><span class="line">*p = 666 // panic: runtime error: invalid memory address or nil pointer dereference</span><br><span class="line"> // 这样操作没有合法向的内存会崩溃</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="new函数的使用"><a href="#new函数的使用" class="headerlink" title="new函数的使用"></a>new函数的使用</h2><figure class="highlight plain"><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">func main() {</span><br><span class="line">var p *int // 声明p为指针类型</span><br><span class="line">p = new(int) // p 指向合法内存,有合法内存后,可以操作内存</span><br><span class="line"> fmt.Printf("p = %v\n", p)</span><br><span class="line">*p = 666 //可以操作内存</span><br><span class="line">fmt.Printf("*p = %v \n", *p)</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="值传递与地址传递"><a href="#值传递与地址传递" class="headerlink" title="值传递与地址传递"></a>值传递与地址传递</h2><figure class="highlight plain"><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">func swap(a, b int) {</span><br><span class="line">a, b = b, a</span><br><span class="line">fmt.Printf("swap:a=%d,b=%d\n", a, b)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">func swap02(p1, p2 *int) {</span><br><span class="line">*p1, *p2 = *p2, *p1</span><br><span class="line">fmt.Printf("swap02:*p1=%d,*p2=%d\n", *p1, *p2)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line">var a, b int = 10, 20</span><br><span class="line">swap(a, b)</span><br><span class="line">fmt.Printf("main:a=%d,b=%d\n", a, b)</span><br><span class="line">swap02(&a, &b) //通过地址交换,从而改变了a,b的内容</span><br><span class="line">fmt.Printf("main:a=%d,b=%d\n", a, b)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> golang </category>
</categories>
<tags>
<tag> go </tag>
<tag> golang </tag>
</tags>
</entry>
<entry>
<title>go 2.19 调用</title>
<link href="/2019/05/17/golang/go-2-19-%E8%B0%83%E7%94%A8_/"/>
<url>/2019/05/17/golang/go-2-19-%E8%B0%83%E7%94%A8_/</url>
<content type="html"><![CDATA[<ul><li><a href="#defer">defer</a></li><li><a href="#defer与匿名函数结合">defer与匿名函数结合</a></li><li><a href="#获取取命令行参数">获取取命令行参数</a></li><li><a href="#包的导入">包的导入</a></li><li><a href="#给导入的包起别名">给导入的包起别名</a></li><li><a href="#导入包的使用">导入包的使用</a></li><li><a href="#关于包的约定">关于包的约定</a></li><li><a href="#下划线引包">下划线引包</a></li></ul><h2 id="defer"><a href="#defer" class="headerlink" title="defer"></a>defer</h2><p>如果一个函数中有多个defer,它们会以LIFO(先进后出)的顺序调用,<br>即使其中有defer调用过程中发生错误,这些调用依旧会执行</p><figure class="highlight plain"><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><br><span class="line">func main() {</span><br><span class="line">defer fmt.Println("in defer") //延迟调用,在main函数结束前调用</span><br><span class="line">fmt.Println("in main")</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight plain"><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">func test(x int) {</span><br><span class="line">fmt.Println(100 / x)</span><br><span class="line">}</span><br><span class="line">func main() {</span><br><span class="line">defer fmt.Println("in defer") //延迟调用,在main函数结束前调用</span><br><span class="line">fmt.Println("in main")</span><br><span class="line">defer fmt.Println("aa")</span><br><span class="line">defer test(0) //这个调用会出现panic,但是后面的defer调用依旧会执行</span><br><span class="line">defer fmt.Println("bb")</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="defer与匿名函数结合"><a href="#defer与匿名函数结合" class="headerlink" title="defer与匿名函数结合"></a>defer与匿名函数结合</h2><figure class="highlight plain"><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">package main</span><br><span class="line"></span><br><span class="line">import (</span><br><span class="line">"fmt"</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line">a := 10</span><br><span class="line">b := 20</span><br><span class="line">defer func(a, b int) {</span><br><span class="line">fmt.Println("in defer func a=", a)</span><br><span class="line">fmt.Println("in defer func b=", b)</span><br><span class="line">}(a, b) //只是传入参数,但未执行,所以执行结果是a=10,b=20,都是未改变的值</span><br><span class="line"></span><br><span class="line">a = 110</span><br><span class="line">b = 220</span><br><span class="line">fmt.Println("in main a=", a)</span><br><span class="line">fmt.Println("in main b=", b)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight plain"><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">package main</span><br><span class="line"></span><br><span class="line">import (</span><br><span class="line">"fmt"</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line">a := 10</span><br><span class="line">b := 20</span><br><span class="line">defer func() {</span><br><span class="line">fmt.Println("in defer func a=", a)</span><br><span class="line">fmt.Println("in defer func b=", b)</span><br><span class="line">}() // 匿名调用 ,调用的是最近变量,所以这里是调用的改变后的a,b的值:110,220</span><br><span class="line"></span><br><span class="line">a = 110</span><br><span class="line">b = 220</span><br><span class="line">fmt.Println("in main a=", a)</span><br><span class="line">fmt.Println("in main b=", b)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="获取取命令行参数"><a href="#获取取命令行参数" class="headerlink" title="获取取命令行参数"></a>获取取命令行参数</h2><figure class="highlight plain"><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">package main</span><br><span class="line"></span><br><span class="line">import (</span><br><span class="line">"fmt"</span><br><span class="line">"os"</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line">list := os.Args</span><br><span class="line">for i, data := range list {</span><br><span class="line">fmt.Printf("os.Args[%v]= %v\n", i, data)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="包的导入"><a href="#包的导入" class="headerlink" title="包的导入"></a>包的导入</h2><p>导入的包必须使用,否则编译不能通过</p><h2 id="给导入的包起别名"><a href="#给导入的包起别名" class="headerlink" title="给导入的包起别名"></a>给导入的包起别名</h2><figure class="highlight plain"><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">package main</span><br><span class="line"></span><br><span class="line">import (</span><br><span class="line">io "fmt" //别名放于包名之前,用空格分隔</span><br><span class="line">"os"</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line">list := os.Args</span><br><span class="line">for i, data := range list {</span><br><span class="line">io.Printf("os.Args[%v]= %v\n", i, data)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="导入包的使用"><a href="#导入包的使用" class="headerlink" title="导入包的使用"></a>导入包的使用</h2><figure class="highlight plain"><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">package main</span><br><span class="line"></span><br><span class="line">import (</span><br><span class="line">. "fmt" // 使用点代替导入的包史,引用时直接使用不用再写包名</span><br><span class="line">. "os"</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line">list := Args // 不写包名,直接使用</span><br><span class="line">for i, data := range list {</span><br><span class="line">Printf("os.Args[%v]= %v\n", i, data) // 不写包名</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="关于包的约定"><a href="#关于包的约定" class="headerlink" title="关于包的约定"></a>关于包的约定</h2><p>1)分文件编程(多个源文件),必须放在src目录<br>2)设置GOPATH环境变量,$GOPATH环境变量必须包括到src的上一级目录<br>3) 同一个目录,包名必须一样<br>4)go env查看go相关的环境路径<br>5) 同一个目录,调用别的文件的函数,无需包名引用,直接调用即可</p><h2 id="下划线引包"><a href="#下划线引包" class="headerlink" title="下划线引包"></a>下划线引包</h2><p>有时,用户可能需要导入一个包,但是不需要引用这个包里的标识符,在这种情况下,可以使用空白标识符_来重命名这个导入<br><figure class="highlight plain"><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">import (</span><br><span class="line"> _ "fmt"</span><br><span class="line"> )</span><br></pre></td></tr></table></figure></p><p>这个操作其实是引用该包,而不直接使用包里的函数,而是调用了该包的init函数</p>]]></content>
<categories>
<category> golang </category>
</categories>
<tags>
<tag> go </tag>
<tag> golang </tag>
</tags>
</entry>
<entry>
<title>go 2.04 函数</title>
<link href="/2019/05/17/golang/go-2-04-%E5%87%BD%E6%95%B0_/"/>
<url>/2019/05/17/golang/go-2-04-%E5%87%BD%E6%95%B0_/</url>
<content type="html"><![CDATA[<ul><li><a href="#普通函数">普通函数</a></li><li><a href="#不定参数函数">不定参数函数</a></li><li><a href="#固定参数与不定参数函数同时写时形参只能放最后">固定参数与不定参数函数同时写时,形参只能放最后</a></li><li><a href="#有返回值函数给返回值起变量名">有返回值函数,给返回值起变量名</a></li><li><a href="#有返回值函数未给返回值起变量名">有返回值函数,未给返回值起变量名</a></li><li><a href="#递归函数调用流程">递归函数调用流程</a></li><li><a href="#使用type定义函数为一种类型">使用type定义函数为一种类型</a></li><li><a href="#匿名函数">匿名函数</a></li></ul><p>函数定义说明:<br>1)函数由关键字func开始声明<br>2)函数首字母小写即为private, 首字母大写即为public<br>3)不支持默认参数</p><h2 id="普通函数"><a href="#普通函数" class="headerlink" title="普通函数"></a>普通函数</h2><figure class="highlight plain"><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">func MyFunc01(a, b int) {</span><br><span class="line">// 等价于func MyFunc01(a int, b int) {</span><br><span class="line">fmt.Println(a)</span><br><span class="line">fmt.Println(b)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line">a := 1</span><br><span class="line">b := 2</span><br><span class="line">MyFunc01(a, b)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="不定参数函数"><a href="#不定参数函数" class="headerlink" title="不定参数函数"></a>不定参数函数</h2><p>函数的传递参数的个数不定,类型确定为同一种类型<br><figure class="highlight plain"><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">// 传递的参数可能是0个或多个</span><br><span class="line">func MyFunc01(args ...int) {</span><br><span class="line">for _, data := range args {</span><br><span class="line">fmt.Println(data)</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line"></span><br><span class="line">a := 1</span><br><span class="line">b := 2</span><br><span class="line">MyFunc01(a, b)</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h2 id="固定参数与不定参数函数同时写时,形参只能放最后"><a href="#固定参数与不定参数函数同时写时,形参只能放最后" class="headerlink" title="固定参数与不定参数函数同时写时,形参只能放最后"></a>固定参数与不定参数函数同时写时,形参只能放最后</h2><figure class="highlight plain"><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">func MyFunc01(a int, args ...int) {</span><br><span class="line">fmt.Println("a = ", a)</span><br><span class="line">for _, data := range args {</span><br><span class="line">fmt.Println("args element value:", data)</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line"></span><br><span class="line">a := 1</span><br><span class="line">b := 2</span><br><span class="line">MyFunc01(a, b)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="有返回值函数-给返回值起变量名"><a href="#有返回值函数-给返回值起变量名" class="headerlink" title="有返回值函数,给返回值起变量名"></a>有返回值函数,给返回值起变量名</h2><figure class="highlight plain"><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">package main</span><br><span class="line"></span><br><span class="line">import (</span><br><span class="line">"fmt"</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">func MyFunc01(a, b int) (result_1, result_2 int) { // 给返回值起变量名</span><br><span class="line">result_1, result_2 = a, b</span><br><span class="line">return</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line">a := 1</span><br><span class="line">b := 2</span><br><span class="line">c, d := MyFunc01(a, b)</span><br><span class="line">fmt.Println(c)</span><br><span class="line">fmt.Println(d)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="有返回值函数-未给返回值起变量名"><a href="#有返回值函数-未给返回值起变量名" class="headerlink" title="有返回值函数,未给返回值起变量名"></a>有返回值函数,未给返回值起变量名</h2><figure class="highlight plain"><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><br><span class="line">func MyFunc01(a, b int) (int, int) { // 不给返回值起变量名,只有返回类型</span><br><span class="line">return a,b</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line">a := 1</span><br><span class="line">b := 2</span><br><span class="line">c, d := MyFunc01(a, b)</span><br><span class="line">fmt.Println(c)</span><br><span class="line">fmt.Println(d)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="递归函数调用流程"><a href="#递归函数调用流程" class="headerlink" title="递归函数调用流程"></a>递归函数调用流程</h2><figure class="highlight plain"><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">package main</span><br><span class="line"></span><br><span class="line">import (</span><br><span class="line">"fmt"</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">func MyFunc01(a int) {</span><br><span class="line">if a == 1 {</span><br><span class="line">fmt.Println("a =", a)</span><br><span class="line">return //终止函数调用</span><br><span class="line">}</span><br><span class="line">MyFunc01(a - 1)</span><br><span class="line">fmt.Println("a =", a)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line">a := 3</span><br><span class="line">MyFunc01(a)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>执行结果:<br>a = 1<br>a = 2<br>a = 3</p><h2 id="使用type定义函数为一种类型"><a href="#使用type定义函数为一种类型" class="headerlink" title="使用type定义函数为一种类型"></a>使用type定义函数为一种类型</h2><p>函数也是一种数据类型,通过type给一个函数类型起名</p><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">package main</span><br><span class="line"></span><br><span class="line">import (</span><br><span class="line">"fmt"</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">func Add(a, b int) int {</span><br><span class="line">return a + b</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">func Minus(a, b int) int {</span><br><span class="line">return a - b</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">type FuncType func(int, int) int // 使用type关键字定义一种函数类型,命名为Functype</span><br><span class="line"></span><br><span class="line">func Calc(a, b int, calc FuncType) int {</span><br><span class="line">return calc(a, b)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line">a := 1</span><br><span class="line">b := 2</span><br><span class="line">result := Calc(a, b, Add)</span><br><span class="line">fmt.Printf("calc result is: %v\n", result)</span><br><span class="line"></span><br><span class="line">result = Calc(a, b, Minus)</span><br><span class="line">fmt.Printf("calc result is: %v\n", result)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="匿名函数"><a href="#匿名函数" class="headerlink" title="匿名函数"></a>匿名函数</h2><figure class="highlight plain"><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">func main() {</span><br><span class="line">a := 3</span><br><span class="line">str := "abc"</span><br><span class="line">func() { //匿名函数:没有函数名称及函数声明</span><br><span class="line">fmt.Println("a = ", a)</span><br><span class="line">fmt.Println("str = ", str)</span><br><span class="line">str = "mike" // 由于闭包引用方式捕获外部变量 ,所以这里会改变函数之外的变量</span><br><span class="line">}() // 使用()调用匿名函数</span><br><span class="line"></span><br><span class="line">fmt.Println(str)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>带参数,带返回值的匿名函数</p><figure class="highlight plain"><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">func main() {</span><br><span class="line">a := 3</span><br><span class="line">str := "abc"</span><br><span class="line">c, d := func(a int, b string) (c int, d string) { //带参数和返回值</span><br><span class="line">fmt.Println("a = ", a)</span><br><span class="line">fmt.Println("str = ", b)</span><br><span class="line">a = 10</span><br><span class="line">c = a</span><br><span class="line">d = "mike"</span><br><span class="line">return</span><br><span class="line">}(a, str) //调用匿名函数,传入参数</span><br><span class="line"></span><br><span class="line">fmt.Println(a)</span><br><span class="line">fmt.Println(str)</span><br><span class="line">fmt.Println(c)</span><br><span class="line">fmt.Println(d)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> golang </category>
</categories>
<tags>
<tag> go </tag>
<tag> golang </tag>
</tags>
</entry>
<entry>
<title>go 1.31 流程控制</title>
<link href="/2019/05/17/golang/go-1-31-%E6%B5%81%E7%A8%8B%E6%8E%A7%E5%88%B6_/"/>
<url>/2019/05/17/golang/go-1-31-%E6%B5%81%E7%A8%8B%E6%8E%A7%E5%88%B6_/</url>
<content type="html"><![CDATA[<ul><li><a href="#if语句">if语句</a></li><li><a href="#switch">switch</a></li><li><a href="#for循环">for循环</a></li><li><a href="#continue跳出本次循环进入下一次循环">continue跳出本次循环,进入下一次循环</a></li><li><a href="#break跳出循环如果多层嵌套循环跳出最近的那个内循环">break跳出循环,如果多层嵌套循环,跳出最近的那个内循环</a></li></ul><h2 id="if语句"><a href="#if语句" class="headerlink" title="if语句"></a>if语句</h2><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">func main() {</span><br><span class="line"></span><br><span class="line">/* 定义局部变量 */</span><br><span class="line">var d int = 10</span><br><span class="line"></span><br><span class="line">/* 使用 if 语句判断布尔表达式 */</span><br><span class="line">if d == 10 {</span><br><span class="line">/* 如果条件为 true 则执行以下语句 */</span><br><span class="line">fmt.Println("d == 10")</span><br><span class="line">} else {</span><br><span class="line">fmt.Println("d != 10")</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"> //if 中的局部变量</span><br><span class="line"> // d的作用域只在if的范围内有效</span><br><span class="line"> if d:=10 ;d == 10 {</span><br><span class="line"> fmt.Println("d == 10")</span><br><span class="line"> } else {</span><br><span class="line"> fmt.Println("d != 10")</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight plain"><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">var e int = 9</span><br><span class="line">if e == 10 {</span><br><span class="line"> fmt.Println("d == 10")</span><br><span class="line">} else if e > 10 {</span><br><span class="line"> fmt.Println("e > 10")</span><br><span class="line">} else if e < 10 {</span><br><span class="line"> fmt.Println("e < 10")</span><br><span class="line">} else {</span><br><span class="line"> fmt.Println("这是不可能的")</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="switch"><a href="#switch" class="headerlink" title="switch"></a>switch</h2><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">package main</span><br><span class="line"></span><br><span class="line">import (</span><br><span class="line">"fmt"</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line">var num int</span><br><span class="line">fmt.Printf("please input floor number:")</span><br><span class="line">fmt.Scan(&num)</span><br><span class="line">switch num { //switch 后面是变量本身</span><br><span class="line">// switch num := 5; num { //switch 支持一个初始化语句,用;分隔</span><br><span class="line">case 1, 5:</span><br><span class="line">fmt.Println("case is 1 or 5")</span><br><span class="line">fallthrough // 不跳出switch语句,后面的条件无条件地执行</span><br><span class="line">case 2:</span><br><span class="line">fmt.Println("case is :", 2)</span><br><span class="line">case 3:</span><br><span class="line">fmt.Println("case is :", 3)</span><br><span class="line">case 4:</span><br><span class="line">fmt.Println("case is :", 4)</span><br><span class="line">default:</span><br><span class="line">fmt.Println("this is default case")</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">// case 判断一个表达式</span><br><span class="line">var grade string</span><br><span class="line">fmt.Printf("please input grade:")</span><br><span class="line">fmt.Scan(&grade)</span><br><span class="line">switch {</span><br><span class="line">case grade == "A":</span><br><span class="line">fmt.Printf("优秀!\n")</span><br><span class="line">case grade == "B", grade == "C":</span><br><span class="line">fmt.Printf("良好\n")</span><br><span class="line">fallthrough // 不跳出switch语句,下一句case无条件地执行</span><br><span class="line">case grade == "D":</span><br><span class="line">fmt.Printf("及格\n")</span><br><span class="line">fallthrough // 不跳出switch语句,下一句case无条件地执行</span><br><span class="line">case grade == "F":</span><br><span class="line">break //跳出switch</span><br><span class="line">fmt.Printf("不及格\n")</span><br><span class="line">default:</span><br><span class="line">fmt.Printf("差\n")</span><br><span class="line">}</span><br><span class="line">fmt.Printf("你输入的grade:%s\n", grade)</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="for循环"><a href="#for循环" class="headerlink" title="for循环"></a>for循环</h2><p>格式:<br>for 初始条件;判断条件;条件变化 {</p><p>}<br>或使用range迭代,下标从0开始<br>for index,data := range iterable_obj {</p><p>}<br><figure class="highlight plain"><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">sum := 0</span><br><span class="line">for i := 1; i < 10; i++ {</span><br><span class="line"> sum = sum + i</span><br><span class="line"> fmt.Println(sum)</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><figure class="highlight plain"><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">str := "abc"</span><br><span class="line">for i, data := range str {</span><br><span class="line"> fmt.Printf("The No. %d element is: %c\n", i, data)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>使用_丢弃返回的下标<br><figure class="highlight plain"><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">str := "abc"</span><br><span class="line">for _, data := range str {</span><br><span class="line"> fmt.Println(data)</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><p>丢弃返回元素,再通过下标取元素<br><figure class="highlight plain"><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">str := "abc"</span><br><span class="line">for i, _ := range str {</span><br><span class="line">fmt.Printf("%c\n", str[i])</span><br><span class="line">}</span><br><span class="line">//等价于:</span><br><span class="line">for i := range str {</span><br><span class="line">fmt.Printf("%c\n", str[i])</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><p>for后面不写任何内容,表示条件永远为值,死循环<br><figure class="highlight plain"><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">for {</span><br><span class="line"> fmt.Println(i)</span><br><span class="line"> if i == 99999 {</span><br><span class="line"> break</span><br><span class="line"> }</span><br><span class="line"> i++</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h2 id="continue跳出本次循环,进入下一次循环"><a href="#continue跳出本次循环,进入下一次循环" class="headerlink" title="continue跳出本次循环,进入下一次循环"></a>continue跳出本次循环,进入下一次循环</h2><h2 id="break跳出循环,如果多层嵌套循环,跳出最近的那个内循环"><a href="#break跳出循环,如果多层嵌套循环,跳出最近的那个内循环" class="headerlink" title="break跳出循环,如果多层嵌套循环,跳出最近的那个内循环"></a>break跳出循环,如果多层嵌套循环,跳出最近的那个内循环</h2>]]></content>
<categories>
<category> golang </category>
</categories>
<tags>
<tag> go </tag>
<tag> golang </tag>
</tags>
</entry>
<entry>
<title>go 1.25 类型转换</title>
<link href="/2019/05/17/golang/go-1-25-%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2/"/>
<url>/2019/05/17/golang/go-1-25-%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2/</url>
<content type="html"><![CDATA[<ul><li><a href="#不兼容类型">不兼容类型</a></li><li><a href="#in-转-string">in 转 string</a></li><li><a href="#string-转-int">string 转 int</a></li><li><a href="#字符类型本质就是整形">字符类型,本质就是整形</a></li><li><a href="#int-转-float32">int 转 float32</a></li><li><a href="#string到float64">string到float64</a></li><li><a href="#string到float32">string到float32</a></li><li><a href="#float64-转成-int">float64 转成 int</a></li></ul><h2 id="不兼容类型"><a href="#不兼容类型" class="headerlink" title="不兼容类型"></a>不兼容类型</h2><p>不能转换的类型,叫不兼容类型<br>如:bool不能转为int,整型也不能转为bool<br>0就是假,非0就是真</p><h2 id="in-转-string"><a href="#in-转-string" class="headerlink" title="in 转 string"></a>in 转 string</h2><figure class="highlight plain"><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">package main</span><br><span class="line"></span><br><span class="line">import (</span><br><span class="line"> "strconv"</span><br><span class="line"> "fmt"</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line"> t := strconv.Itoa(123) //整型转字条串</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="string-转-int"><a href="#string-转-int" class="headerlink" title="string 转 int"></a>string 转 int</h2><figure class="highlight plain"><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">i, _ := strconv.Atoi("100")</span><br><span class="line">fmt.Println(i)</span><br></pre></td></tr></table></figure><h2 id="字符类型,本质就是整形"><a href="#字符类型,本质就是整形" class="headerlink" title="字符类型,本质就是整形"></a>字符类型,本质就是整形</h2><p>如:<br><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">package main</span><br><span class="line"></span><br><span class="line">import (</span><br><span class="line">"fmt"</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line">var ch byte</span><br><span class="line">ch = 'a'</span><br><span class="line">var t int</span><br><span class="line">t = int(ch) //类型转换,把ch的值取出来,转成int再赋值给t</span><br><span class="line">fmt.Println("t = ", t)</span><br><span class="line">fmt.Printf("t = %c", t) // 格式化为字符再输出</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h2 id="int-转-float32"><a href="#int-转-float32" class="headerlink" title="int 转 float32"></a>int 转 float32</h2><figure class="highlight plain"><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">var sum int = 17</span><br><span class="line">var count int = 5</span><br><span class="line">var mean float32</span><br><span class="line"></span><br><span class="line">mean = float32(sum)/float32(count)</span><br><span class="line">fmt.Printf("mean 的值为: %f\n",mean)</span><br></pre></td></tr></table></figure><h2 id="string到float64"><a href="#string到float64" class="headerlink" title="string到float64"></a>string到float64</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">float,err := strconv.ParseFloat(string,64)</span><br></pre></td></tr></table></figure><h2 id="string到float32"><a href="#string到float32" class="headerlink" title="string到float32"></a>string到float32</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">float,err := strconv.ParseFloat(string,32)</span><br></pre></td></tr></table></figure><h2 id="float64-转成-int"><a href="#float64-转成-int" class="headerlink" title="float64 转成 int"></a>float64 转成 int</h2><figure class="highlight plain"><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">var a float64</span><br><span class="line">a = 1.9</span><br><span class="line">b := int(a)</span><br><span class="line">fmt.Println(a, b)</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> golang </category>
</categories>
<tags>
<tag> go </tag>
<tag> golang </tag>
</tags>
</entry>
<entry>
<title>go 1.16 格式化输出和用户输入</title>
<link href="/2019/05/17/golang/go-1-16-%E6%A0%BC%E5%BC%8F%E5%8C%96%E8%BE%93%E5%87%BA%E5%92%8C%E7%94%A8%E6%88%B7%E8%BE%93%E5%85%A5/"/>
<url>/2019/05/17/golang/go-1-16-%E6%A0%BC%E5%BC%8F%E5%8C%96%E8%BE%93%E5%87%BA%E5%92%8C%E7%94%A8%E6%88%B7%E8%BE%93%E5%85%A5/</url>
<content type="html"><![CDATA[<ul><li><a href="#格式化输出">格式化输出</a></li><li><a href="#接受用户输入">接受用户输入</a></li></ul><h2 id="格式化输出"><a href="#格式化输出" class="headerlink" title="格式化输出"></a>格式化输出</h2><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">package main</span><br><span class="line"></span><br><span class="line">import (</span><br><span class="line">"fmt"</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line">a := 10</span><br><span class="line">b := "abc"</span><br><span class="line">c := 'a'</span><br><span class="line">d := 3.14</span><br><span class="line">fmt.Printf("%T,%T,%T,%T\n", c, b, c, d) // %T 操作变量所属的类型</span><br><span class="line">//%d 整形格式</span><br><span class="line">//%s 字符串格式</span><br><span class="line">//%c 字符格式</span><br><span class="line">//%f 浮点格式</span><br><span class="line">// %v 自动匹配格式输出</span><br><span class="line">fmt.Printf("a = %d,b = %s,c = %c,d = %f\n", a, b, c, d)</span><br><span class="line">fmt.Printf("a = %v,b = %v,c = %v,d = %v\n", a, b, c, d)</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="接受用户输入"><a href="#接受用户输入" class="headerlink" title="接受用户输入"></a>接受用户输入</h2><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">package main</span><br><span class="line"></span><br><span class="line">import (</span><br><span class="line">"fmt"</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line"></span><br><span class="line">var input_num int</span><br><span class="line">fmt.Printf("please input numbers:")</span><br><span class="line"> //阻塞,等待用户输入</span><br><span class="line">fmt.Scan(&input_num) // 注意,这里是取input_num的内存地址</span><br><span class="line">fmt.Print("input_num = ", input_num)</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> golang </category>
</categories>
<tags>
<tag> go </tag>
<tag> golang </tag>
</tags>
</entry>
<entry>
<title>go 1.07 变量</title>
<link href="/2019/05/17/golang/go-1-07-%E5%8F%98%E9%87%8F/"/>
<url>/2019/05/17/golang/go-1-07-%E5%8F%98%E9%87%8F/</url>
<content type="html"><![CDATA[<ul><li><a href="#变量名命名规范">变量名命名规范:</a></li><li><a href="#关键字">关键字</a></li><li><a href="#变量声明">变量声明</a></li><li><a href="#关于输出格式">关于输出格式</a></li><li><a href="#注意">注意:</a></li></ul><h2 id="变量名命名规范:"><a href="#变量名命名规范:" class="headerlink" title="变量名命名规范:"></a>变量名命名规范:</h2><p>1)组成只能是:字母,数字,下划线<br>2)不能以数字开头<br>3)名字不能是关键字<br>4)区分大小写</p><h2 id="关键字"><a href="#关键字" class="headerlink" title="关键字"></a>关键字</h2><p>下面列举了 Go 代码中会使用到的 25 个关键字或保留字:</p><table><thead><tr><th>——–</th><th>———–</th><th>——</th><th>———</th><th>——</th></tr></thead><tbody><tr><td>break</td><td>default</td><td>func</td><td>interface</td><td>select</td></tr><tr><td>case</td><td>defer</td><td>go</td><td>map</td><td>struct</td></tr><tr><td>chan</td><td>else</td><td>goto</td><td>package</td><td>switch</td></tr><tr><td>const</td><td>fallthrough</td><td>if</td><td>range</td><td>type</td></tr><tr><td>continue</td><td>for</td><td>import</td><td>return</td><td>var</td></tr></tbody></table><p>除了以上介绍的这些关键字,Go 语言还有 36 个预定义标识符:</p><table><thead><tr><th>——</th><th>——-</th><th>——-</th><th>——-</th><th>——</th><th>——-</th><th>———</th><th>———-</th><th>——-</th></tr></thead><tbody><tr><td>append</td><td>bool</td><td>byte</td><td>cap</td><td>close</td><td>complex</td><td>complex64</td><td>complex128</td><td>uint16</td></tr><tr><td>copy</td><td>false</td><td>float32</td><td>float64</td><td>imag</td><td>int</td><td>int8</td><td>int16</td><td>uint32</td></tr><tr><td>int32</td><td>int64</td><td>iota</td><td>len</td><td>make</td><td>new</td><td>nil</td><td>panic</td><td>uint64</td></tr><tr><td>print</td><td>println</td><td>real</td><td>recover</td><td>string</td><td>true</td><td>uint</td><td>uint8</td><td>uintptr</td></tr></tbody></table><h2 id="变量声明"><a href="#变量声明" class="headerlink" title="变量声明"></a>变量声明</h2><p>1)声明格式:var 变量名 类型<br>2)变量声明后,必须要使用<br>3)只是声明,没有初始化的变量,默认值为0<br>4)同一个 {} 中的变量名是唯一的<br>5)可以同时声明多个变量,如var a,b,c int</p><p>变量声明举例:<br><figure class="highlight plain"><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">var a int</span><br><span class="line">var b int = 10</span><br><span class="line">c := 20 //自动推导类型</span><br><span class="line">i,j := 10,20 //多重变量赋值</span><br><span class="line">i,j = j,i //变量交换</span><br><span class="line">var tmp</span><br><span class="line">tmp,_ = i,j // _为匿名变量,丢弃数据,不处理</span><br></pre></td></tr></table></figure></p><p>代码示例:<br><figure class="highlight plain"><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">package main</span><br><span class="line"></span><br><span class="line">import (</span><br><span class="line">"fmt"</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">func main() {</span><br><span class="line">a := 10</span><br><span class="line">fmt.Printf("c type is %T\n", a)</span><br><span class="line">// %T打印变量的所属的类型</span><br><span class="line"> // fmt.Printf 不换行输出,如果需要换行,则需要手动增加 \n 到输出之字符串的末尾</span><br><span class="line"> // fmt.Println 自动换行输出</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h2 id="关于输出格式"><a href="#关于输出格式" class="headerlink" title="关于输出格式"></a>关于输出格式</h2><figure class="highlight plain"><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">%d 整形格式</span><br><span class="line">%s 字符串格式</span><br><span class="line">%c 字符格式</span><br><span class="line">%f 浮点格式</span><br><span class="line">%v 自动匹配格式输出</span><br></pre></td></tr></table></figure><h2 id="注意:"><a href="#注意:" class="headerlink" title="注意:"></a>注意:</h2><figure class="highlight plain"><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">在liteIDE中编译运行代码时,源代码的文件不能*_test.go结尾,</span><br><span class="line">否则编译不过,报错:</span><br><span class="line">go build <dir>: no non-test Go files in <dir></span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> golang </category>
</categories>
<tags>
<tag> go </tag>
<tag> golang </tag>
</tags>
</entry>
<entry>
<title>go 1.03 环境搭建</title>
<link href="/2019/05/17/golang/go-1-03-%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA_/"/>
<url>/2019/05/17/golang/go-1-03-%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA_/</url>
<content type="html"><![CDATA[<ul><li><a href="#go开发环境搭建">go开发环境搭建</a><ul><li><a href="#下载go安装包">下载go安装包</a></li><li><a href="#下载开发ide我使用liteide">下载开发IDE,我使用liteIDE</a></li><li><a href="#安装下载好的包-解压到需要的路径即可">安装下载好的包–解压到需要的路径即可</a></li><li><a href="#设置系统环境变量和创建开发工程目录">设置系统环境变量和创建开发工程目录</a></li><li><a href="#缺少libstdcso6而摄错">缺少libstdc++.so.6而摄错</a></li><li><a href="#go命令">go命令</a></li><li><a href="#go的目录结构">go的目录结构</a></li></ul></li></ul><h1 id="go开发环境搭建"><a href="#go开发环境搭建" class="headerlink" title="go开发环境搭建"></a>go开发环境搭建</h1><h2 id="下载go安装包"><a href="#下载go安装包" class="headerlink" title="下载go安装包"></a>下载go安装包</h2><p>官网下载页面:<br><a href="https://golang.org/dl/" target="_blank" rel="noopener">https://golang.org/dl/</a><br>中文社区下载页面:<br><a href="https://studygolang.com/dl" target="_blank" rel="noopener">https://studygolang.com/dl</a><br>linux系统,下载链接:<br><a href="https://dl.google.com/go/go1.12.5.linux-amd64.tar.gz" target="_blank" rel="noopener">https://dl.google.com/go/go1.12.5.linux-amd64.tar.gz</a><br>安装文档介绍:<br><a href="http://docs.studygolang.com/doc/install" target="_blank" rel="noopener">http://docs.studygolang.com/doc/install</a></p><h2 id="下载开发IDE,我使用liteIDE"><a href="#下载开发IDE,我使用liteIDE" class="headerlink" title="下载开发IDE,我使用liteIDE"></a>下载开发IDE,我使用liteIDE</h2><p>下载页面:<a href="http://liteide.org/cn/" target="_blank" rel="noopener">http://liteide.org/cn/</a><br>选一个下载地址:<a href="https://github.com/visualfc/liteide/releases/download/x36/liteidex36.linux64-qt5.5.1.tar.gz" target="_blank" rel="noopener">https://github.com/visualfc/liteide/releases/download/x36/liteidex36.linux64-qt5.5.1.tar.gz</a></p><h2 id="安装下载好的包–解压到需要的路径即可"><a href="#安装下载好的包–解压到需要的路径即可" class="headerlink" title="安装下载好的包–解压到需要的路径即可"></a>安装下载好的包–解压到需要的路径即可</h2><p>golang:<br>sudo tar -C /usr/local -xzf go1.12.5.linux-amd64.tar.gz</p><p>liteide:<br>sudo tar -C /usr/local -xzf liteidex36.linux64-qt5.5.1.tar.gz</p><h2 id="设置系统环境变量和创建开发工程目录"><a href="#设置系统环境变量和创建开发工程目录" class="headerlink" title="设置系统环境变量和创建开发工程目录"></a>设置系统环境变量和创建开发工程目录</h2><figure class="highlight plain"><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">#!/bin/bash</span><br><span class="line"># 创建开发代码的工程目录,并追加到GOPATH环境变量</span><br><span class="line">mkdir -p ~/go/src</span><br><span class="line">echo 'export GOPATH=$HOME/go' >> ~/.bashrc</span><br><span class="line"># 把go的安装目录追加到PATH环境变量</span><br><span class="line">echo 'export PATH=$PATH:$GOPATH/bin:/usr/local/go/bin' >> ~/.bashrc</span><br><span class="line">source ~/.bashrc</span><br><span class="line"># 使用go version 验证go安装是否成功</span><br><span class="line">go version</span><br><span class="line"># 追加liteide的安装路径到PATH环境变量</span><br><span class="line"></span><br><span class="line">echo 'export PATH=/usr/local/liteide/bin:$PATH' >> ~/.bashrc</span><br></pre></td></tr></table></figure><h2 id="缺少libstdc-so-6而摄错"><a href="#缺少libstdc-so-6而摄错" class="headerlink" title="缺少libstdc++.so.6而摄错"></a>缺少libstdc++.so.6而摄错</h2><p>如果是在ubuntu14.04上运行liteIDE,可以会遇到如下报错<br><figure class="highlight plain"><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">liteide: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /usr/local/liteide/bin/../lib/libQt5Core.so.5)</span><br><span class="line">liteide: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /usr/local/liteide/bin/../lib/libicui18n.so.55)</span><br><span class="line">liteide: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /usr/local/liteide/bin/../lib/libicuuc.so.55)</span><br></pre></td></tr></table></figure></p><p>解决办法:<br>从ubuntu18的机器上找到libstdc++.so.6,复制到 /usr/local/liteide/lib/libstdc++.so.6<br>再启动即可</p><p>参考链接:<a href="https://github.com/visualfc/liteide/issues/961" target="_blank" rel="noopener">https://github.com/visualfc/liteide/issues/961</a></p><h2 id="go命令"><a href="#go命令" class="headerlink" title="go命令"></a>go命令</h2><p>go build xxx.go<br>此命令只会编译代码,不能运行可执行程序<br>go run xxx.go<br>此命令只会执行go文件,不会编译成可执行程序</p><h2 id="go的目录结构"><a href="#go的目录结构" class="headerlink" title="go的目录结构"></a>go的目录结构</h2><figure class="highlight plain"><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">goproject/</span><br><span class="line">└── src</span><br><span class="line"> └── gocode</span><br><span class="line"> └── project01</span><br><span class="line"> ├── main</span><br><span class="line"> └── package_name_dir</span><br></pre></td></tr></table></figure><p>这样的结构,那么就设定GOPATH=xxxxx/goproject</p>]]></content>
<categories>
<category> golang </category>
</categories>
<tags>
<tag> go </tag>
<tag> golang </tag>
</tags>
</entry>
<entry>
<title>recommand_bwhost</title>
<link href="/2019/03/18/other/recommand_bwhost/"/>
<url>/2019/03/18/other/recommand_bwhost/</url>
<content type="html"><![CDATA[<h1 id="VPS推荐链接"><a href="#VPS推荐链接" class="headerlink" title="VPS推荐链接"></a>VPS推荐链接</h1><figure class="highlight plain"><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">https://open.work.weixin.qq.com/wwopen/mpnews?mixuin=3kAlBgAABwC8DWdcAAAUAA&mfid=WW0323-0pMx0gAABwCyNzOp44Cc9AeLIJ43a&idx=0&sn=8c4812ceb9b1de4118f37b61b6398482</span><br><span class="line"></span><br><span class="line">https://bandwagonhost.com/aff.php?aff=45216</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 其它 </category>
</categories>
<tags>
<tag> vps </tag>
</tags>
</entry>
<entry>
<title>install confluence</title>
<link href="/2017/03/23/tools/install-confluence/"/>
<url>/2017/03/23/tools/install-confluence/</url>
<content type="html"><![CDATA[<ul><li><a href="#准备工作">准备工作</a></li><li><a href="#启动confluence">启动confluence</a></li><li><a href="#破解">破解</a></li></ul><h1 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h1><p>1.创建目录<br>mkdir -p /data/atlassian/confluence/{conf_home,conf_install}<br>2.修改权限<br>chown -R daemon:daemon /data/atlassian/confluence<br>3.创建启动脚本,并修改权限<br>cat /opt/run_confluence.sh<br>chmod +x /opt/run_confluence.sh</p><figure class="highlight plain"><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">#!/bin/bash</span><br><span class="line">name="confluence-container"</span><br><span class="line">docker stop ${name} && docker rm -v ${name}</span><br><span class="line">/usr/bin/docker run --restart=always -d --name "confluence-container" \</span><br><span class="line"> -p "8090:8090" \</span><br><span class="line"> -v "/data/atlassian/confluence/conf_home:/var/atlassian/confluence" \</span><br><span class="line"> cptactionhank/atlassian-confluence:5.8.10</span><br></pre></td></tr></table></figure><h1 id="启动confluence"><a href="#启动confluence" class="headerlink" title="启动confluence"></a>启动confluence</h1><p>1./opt/run_confluence.sh</p><p>2.使用浏览器打开192.168.0.93:8090,选择Production Installation,并占击Next<br><img src="/assets/markdown-img-paste-20180814140754458.png" alt="access_confluence_page1"></p><p>3.记录下Server ID,如:BI31-0PSH-5SYG-6OX8<br>4.暂时停止confluence<br>docker stop confluence-container</p><p>5.查找docker中的atlassian-extras-decoder-v2-3.2.jar<br>find /data/docker/local-storage/docker/ -name “atlassian-extras-decoder-v2-3.2.jar”</p><p>/data/docker/local-storage/docker/aufs/diff/983d62f805befea70fd9c46019a356e3c762b9c929c20ec6c5c37ec0855b091b/usr/local/atlassian/confluence/confluence/WEB-INF/lib/atlassian-extras-decoder-v2-3.2.jar</p><h1 id="破解"><a href="#破解" class="headerlink" title="破解"></a>破解</h1><p>1.重命名atlassian-extras-decoder-v2-3.2.jar为 atlassian-extras-2.4.jar<br>2.解压confluence5.1-crack.zip<br>进入confluence5.1-crack/iNViSiBLE$,执行:keygen.sh</p><p>3.输入name:test1234,这个可以随意,输入之前记录的Server ID</p><p>4.把重新生成的文件重命名,并替换回原路径</p><p>5.单击复制key到剪贴板</p><figure class="highlight plain"><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">AAABMA0ODAoPeJxtkMlqwzAQQO/6CkHPCl6SxgQEVWzRmnoJtVOao+JOUoGjBC2m+fsqcX0phbnM9</span><br><span class="line">ngzD60DzNwRh3MfqzhZRUucNi2OgjBBGZhOy4uVZ0XTszr0DlQHqHKnPej6sDWgDSUhSjWI21AmL</span><br><span class="line">NDbJgkSEs6R37Gis5U4AbVgbBjFc9R50MxX5eCL2sE0xUsheyrVII3c9/BkOlAwUz3ig+jdnU8Po</span><br><span class="line">jcwEgrp+wba6wXu/LQuS/6W5qxAHqQsKOFd+fdF6uvoFcdLEkYkWoyA6Yq0d8aCrs6fYGiAGl7RX</span><br><span class="line">b3FJXvluOSY4YZleMOqjM1QrY9CSTPKyOpdNnJdcNxyVqIG9AA6z+g6j0MSbJoXsmh2z+Sx/kjQr</span><br><span class="line">63vFnk2Zf/LbZzuvoSBP8/8ATV6iRMwLAIUC/RpFxXPfEauHjG2QJ3yZ3rukxICFCHDIGkAmCgee</span><br><span class="line">NteYVIYb725rgNrX02f7</span><br></pre></td></tr></table></figure><p>6.启动conflucen,打开<a href="http://ip:8090,填写上一步复制的key" target="_blank" rel="noopener">http://ip:8090,填写上一步复制的key</a><br>7.本文只是记录安装体验过程,商业用途请支持正版</p>]]></content>
<categories>
<category> 工具 </category>
</categories>
<tags>
<tag> confluence </tag>
</tags>
</entry>
<entry>
<title>3-hexo使用说明</title>
<link href="/2017/03/23/3-hexo-instruction/"/>
<url>/2017/03/23/3-hexo-instruction/</url>
<content type="html"><![CDATA[<blockquote><p>下面如果没有特殊说明, <code>_config.yml</code> 都指主题配置文件,即 <code>3-hexo</code> 目录下</p></blockquote><h2 id="自定义首页"><a href="#自定义首页" class="headerlink" title="自定义首页"></a>自定义首页</h2><p>可查看这篇文章: </p><h2 id="blog快捷键"><a href="#blog快捷键" class="headerlink" title="blog快捷键"></a>blog快捷键</h2><p>可查看这篇文章: </p><h2 id="更换头像"><a href="#更换头像" class="headerlink" title="更换头像"></a>更换头像</h2><p>两种方式:</p><ol><li>替换 <code>source/img/avatar.jpg</code> 图片。</li><li>修改 <code>_config.yml</code> 中头像的配置记录</li></ol><figure class="highlight xml"><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"># 你的头像url</span><br><span class="line">avatar: /img/avatar.jpg</span><br><span class="line">favicon: /img/avatar.jpg</span><br></pre></td></tr></table></figure><h2 id="设置链接图标"><a href="#设置链接图标" class="headerlink" title="设置链接图标"></a>设置链接图标</h2><p>如下,如果没有连接,则不展示图标。<br><figure class="highlight xml"><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><br><span class="line">link:</span><br><span class="line"> rss: /atom.xml</span><br><span class="line"> github: https://github.com/yelog</span><br><span class="line"> facebook: https://www.facebook.com/faker.tops</span><br><span class="line"> twitter:</span><br><span class="line"> linkedin:</span><br><span class="line"> instagram:</span><br><span class="line"> reddit: https://www.reddit.com/user/yelog/</span><br><span class="line"> weibo: http://weibo.com/u/2307534817</span><br><span class="line"> email: [email protected]</span><br></pre></td></tr></table></figure></p><h2 id="开启关于页面"><a href="#开启关于页面" class="headerlink" title="开启关于页面"></a>开启<code>关于</code>页面</h2><ol><li><p>在 <code>hexo</code> 根目录执行以下,创建 <code>关于</code> 页面</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">hexo new page <span class="string">"about"</span></span><br></pre></td></tr></table></figure></li><li><p>位置: <code>source/aoubt/index.md</code> ,根据需要进行编辑。</p></li><li>在主题中开启显示:修改主题根目录 <code>_config.yml</code> 中的 <code>about</code> 的 <code>on</code> 为 <code>true</code>,如下所示<figure class="highlight yml"><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="attr">menu:</span></span><br><span class="line"><span class="attr"> about:</span> <span class="comment"># '关于' 按钮</span></span><br><span class="line"><span class="attr"> on:</span> <span class="literal">true</span> <span class="comment"># 是否显示</span></span><br><span class="line"><span class="attr"> url:</span> <span class="string">/about</span> <span class="comment"># 跳转链接</span></span><br><span class="line"><span class="attr"> type:</span> <span class="number">1</span> <span class="comment"># 跳转类型 1:站内异步跳转 2:当前页面跳转 3:打开新的tab页</span></span><br></pre></td></tr></table></figure></li></ol><h2 id="配置评论系统"><a href="#配置评论系统" class="headerlink" title="配置评论系统"></a>配置评论系统</h2><p>目前添加了三种评论系统 <strong>disqus、多说、网易云跟帖</strong></p><blockquote><p><code>日志:</code> 2017-03-21:多说将于2017-06-01正式关停服务</p></blockquote><h3 id="启用评论"><a href="#启用评论" class="headerlink" title="启用评论"></a>启用评论</h3><p>以 <code>disqus</code> 为例;</p><ol><li>关掉其他两个评论(设置on: false)</li><li>启用 <code>disqus</code> ,设置on: true</li><li>登陆 <code>disqus</code> 注册,得到shortname,填入shortname。</li><li>重启 <code>hexo</code>。</li></ol><h3 id="meta区显示评论数"><a href="#meta区显示评论数" class="headerlink" title="meta区显示评论数"></a>meta区显示评论数</h3><p>开启设置 <code>_config.yml</code><br><figure class="highlight xml"><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">comment_count: true</span><br><span class="line"># 文章标题下方显示评论数</span><br></pre></td></tr></table></figure></p><p><img src="http://img.xiangzhangshugongyi.com/FlDHXpVnJ-ECFCehRBoKkQMlqj_R.png" alt="开启效果"></p><h3 id="评论区预加载"><a href="#评论区预加载" class="headerlink" title="评论区预加载"></a>评论区预加载</h3><p>开启设置 <code>_config.yml</code><br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">preload_comment: false</span><br></pre></td></tr></table></figure></p><ol><li>false: 当点击评论条等区域时再加载评论模块</li><li>true: 页面加载时加载评论区</li></ol><p><img src="http://img.xiangzhangshugongyi.com/FrYn2xsPMLBizQZ_p_mCa-hJYTG_.png" alt="关闭效果"></p><h2 id="样式设置"><a href="#样式设置" class="headerlink" title="样式设置"></a>样式设置</h2><h3 id="代码高亮"><a href="#代码高亮" class="headerlink" title="代码高亮"></a>代码高亮</h3><p>首先要关闭hexo根目录下<code>_config.yml</code>中的高亮设置:<br><figure class="highlight xml"><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">highlight:</span><br><span class="line"> enable: false</span><br></pre></td></tr></table></figure></p><p>配置主题下<code>_config.yml</code>中的高亮设置:<br>可以根据提示,配置喜欢的高亮主题<br><figure class="highlight xml"><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></pre></td><td class="code"><pre><span class="line">highlight:</span><br><span class="line"> on: true # true开启代码高亮</span><br><span class="line"> lineNum: true # true显示行号</span><br><span class="line"> theme: darcula</span><br><span class="line"># 代码高亮主题,效果可以查看 https://highlightjs.org/static/demo/</span><br><span class="line"># 支持主题:</span><br><span class="line"># sublime : 参考sublime的高亮主题</span><br><span class="line"># darcula : 参考idea中的darcula的主题</span><br><span class="line"># atom-dark : 参考Atom的dark主题</span><br><span class="line"># atom-light : 参考Atom的light主题</span><br><span class="line"># github : 参考GitHub版的高亮主题</span><br><span class="line"># github-gist : GitHub-Gist主题</span><br><span class="line"># brown-paper : 牛皮纸效果</span><br><span class="line"># gruvbox-light : gruvbox的light主题</span><br><span class="line"># gruvbox-dark : gruvbox的dark主题</span><br><span class="line"># rainbow :</span><br><span class="line"># railscasts :</span><br><span class="line"># sunburst :</span><br><span class="line"># kimbie-dark :</span><br><span class="line"># kimbie-light :</span><br><span class="line"># school-book : 纸张效果</span><br></pre></td></tr></table></figure></p><h3 id="MathJax数学公式"><a href="#MathJax数学公式" class="headerlink" title="MathJax数学公式"></a>MathJax数学公式</h3><p>修改 <code>_config.yml</code><br><figure class="highlight xml"><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"># MathJax 数学公式支持</span><br><span class="line">mathjax:</span><br><span class="line"> on: true #是否启用</span><br><span class="line"> per_page: false # 若只渲染单个页面,此选项设为false,页面内加入 mathjax: true</span><br></pre></td></tr></table></figure></p><p>考虑到页面的加载速度,支持渲染单个页面。<br>设置 <code>per_page: false</code> ,在需要渲染的页面内 加入 <code>mathjax: true</code></p><blockquote><p><strong><code>注意:</code></strong><br>由于hexo的MarkDown渲染器与MathJax有冲突,可能会造成矩阵等使用不正常。所以在使用之前需要修改两个地方<br>编辑 <code>node_modules\marked\lib\marked.js</code> 脚本</p></blockquote><ol><li><p>将451行 ,这一步取消了对 <code>\\,\{,\}</code> 的转义(escape)</p><figure class="highlight js"><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="built_in">escape</span>: <span class="regexp">/^\\([\\`*{}\[\]()# +\-.!_>])/</span>,</span><br><span class="line">改为</span><br><span class="line"><span class="built_in">escape</span>: <span class="regexp">/^\\([`*\[\]()# +\-.!_>])/</span>,</span><br></pre></td></tr></table></figure></li><li><p>将459行,这一步取消了对斜体标记 <code>_</code> 的转义</p><figure class="highlight js"><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">em: <span class="regexp">/^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/</span>,</span><br><span class="line">改为</span><br><span class="line">em:<span class="regexp">/^\*((?:\*\*|[\s\S])+?)\*(?!\*)/</span>,</span><br></pre></td></tr></table></figure></li></ol><h3 id="表格样式"><a href="#表格样式" class="headerlink" title="表格样式"></a>表格样式</h3><p>目前提供了3中样式,修改 <code>_config.yml</code><br><figure class="highlight xml"><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">table: green_title</span><br><span class="line"># table 的样式</span><br><span class="line"># 为空时类似github的table样式</span><br><span class="line"># green 绿色样式</span><br><span class="line"># green_title 头部为青色的table样式</span><br></pre></td></tr></table></figure></p><h3 id="文章列表的hover样式"><a href="#文章列表的hover样式" class="headerlink" title="文章列表的hover样式"></a>文章列表的hover样式</h3><p>鼠标移入的背景色和文字颜色变动,设置 <code>_config.yml</code><br><figure class="highlight xml"><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><br><span class="line">article_list:</span><br><span class="line"> hover:</span><br><span class="line"> background: '#e2e0e0' # 背景色:提供几种:'#c1bfc1' '#fbf4a8'</span><br><span class="line"> color: # 文字颜色 提供几种:'#ffffff'</span><br><span class="line"># 注意:由于颜色如果包含#,使用单引号 ' 引起来</span><br></pre></td></tr></table></figure></p><h2 id="开启字数统计"><a href="#开启字数统计" class="headerlink" title="开启字数统计"></a>开启字数统计</h2><ol><li>开启此功能需先安装插件,在 hexo根目录 执行 <code>npm i hexo-wordcount --save</code></li><li>修改 <code>_config.yml</code></li></ol><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">word_count: true</span><br></pre></td></tr></table></figure><h2 id="多作者模式"><a href="#多作者模式" class="headerlink" title="多作者模式"></a>多作者模式</h2><p>可查看这篇文章: </p><h2 id="文章排序及置顶"><a href="#文章排序及置顶" class="headerlink" title="文章排序及置顶"></a>文章排序及置顶</h2><p>可查看这篇文章: </p><h2 id="关于写文章"><a href="#关于写文章" class="headerlink" title="关于写文章"></a>关于写文章</h2><h3 id="如何写"><a href="#如何写" class="headerlink" title="如何写"></a>如何写</h3><p>每篇文章最好写上文集和标签,方便筛选和查看。<br>一般推荐一篇文章设置一个文集,一个或多个标签<br><code>categories</code>:文集,为左侧列表<br><code>tags</code>:标签,通过#来筛选<br>例如 本篇文章的设置<br><figure class="highlight xml"><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><br><span class="line">title: 3-hexo使用说明</span><br><span class="line">date: 2017-03-23 15:13:47</span><br><span class="line">categories:</span><br><span class="line">- 工具</span><br><span class="line">tags:</span><br><span class="line">- hexo</span><br><span class="line">- 3-hexo</span><br><span class="line">---</span><br></pre></td></tr></table></figure></p><h3 id="写作"><a href="#写作" class="headerlink" title="写作"></a>写作</h3><p>1.设置模板,blog根目录 <code>scaffolds/post.md</code><br>加入categories,tags等,这样以后通过 <code>hexo new</code> 生成的模板就不用写这两个单词了。<br>当然,你也可以写入任何你每个文章中都会有的部分。<br><figure class="highlight xml"><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><br><span class="line">title: {{ title }}</span><br><span class="line">date: {{ date }}</span><br><span class="line">categories:</span><br><span class="line">tags:</span><br><span class="line">---</span><br></pre></td></tr></table></figure></p><h2 id="技巧"><a href="#技巧" class="headerlink" title="技巧"></a>技巧</h2><h3 id="快捷命令"><a href="#快捷命令" class="headerlink" title="快捷命令"></a>快捷命令</h3><p>其实就通过alias,触发一些命令的集合<br>在 <code>~/.bashrc</code> 文件中添加<br><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">alias</span> hs=<span class="string">'hexo clean && hexo g && hexo s'</span> <span class="comment">#启动本地服务</span></span><br><span class="line"><span class="built_in">alias</span> hd=<span class="string">'hexo clean && hexo g && hexo d'</span> <span class="comment">#部署博客</span></span><br></pre></td></tr></table></figure></p><p>甚至你也可以加入备份文章的命令,可以自由发挥。</p><h3 id="博客备份(快捷命令升级版)"><a href="#博客备份(快捷命令升级版)" class="headerlink" title="博客备份(快捷命令升级版)"></a>博客备份(快捷命令升级版)</h3><p>为了保证我们写的文章不丢失、快速迁移博客,都需要备份我们的blog。</p><ol><li>博客根目录,执行 <code>git init</code> 创建 git 仓库。</li><li>在 github(或其他托管平台、自建远程仓库等) 创建仓库并和本地仓库建立联系。</li><li>在 <code>~/.bashrc</code> 文件中添加<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">alias</span> hs=<span class="string">'hexo clean && hexo g && hexo s'</span></span><br><span class="line"><span class="built_in">alias</span> hd=<span class="string">'hexo clean && hexo g && hexo d && git add . && git commit -m "update" && git push -f'</span></span><br></pre></td></tr></table></figure></li></ol><p>这样,我们在执行 <code>hd</code> 进行部署时,就一同将博客进行备份了</p>]]></content>
<categories>
<category> 工具 </category>
</categories>
<tags>
<tag> hexo </tag>
<tag> 3-hexo </tag>
</tags>
</entry>
</search>