-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.xml
1820 lines (1737 loc) · 250 KB
/
index.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
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Twor</title>
<link>https://twor.me/</link>
<description>Recent content on Twor</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<lastBuildDate>Sun, 18 Dec 2022 14:36:02 +0800</lastBuildDate>
<atom:link href="https://twor.me/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Cloudflared</title>
<link>https://twor.me/posts/cloudflared/</link>
<pubDate>Sun, 18 Dec 2022 14:36:02 +0800</pubDate>
<guid>https://twor.me/posts/cloudflared/</guid>
<description><p>cloudflared 免备案使用国内服务器</p>
<p>需要下载 cloudflared 并拥有一个 Cloudflare 帐号,域名解析在cloudflare</p>
<h3 id="下载cloudflare">下载cloudflare</h3>
<p><a href="https://github.com/cloudflare/cloudflared">https://github.com/cloudflare/cloudflared</a></p>
<h3 id="授权域名">授权域名</h3>
<p>运行 <code>cloudflared tunnel login</code>,登录cloudflare帐号,并在浏览器中选择一个域名来授权。
你的家目录中会出现 ~/.cloudflared/cert.pem。在我们创建隧道和设置 DNS 解析的时候,我们会用到这个文件。</p>
<h3 id="创建隧道">创建隧道</h3>
<p>运行 cloudflared tunnel create [名字],创建一个隧道。这条命令需要之前的 cert.pem 用来验证身份。
你的家目录中会出现 ~/.cloudflared/[一长串UUID].json,里面保存这运行这条隧道所需要的授权信息。</p>
<h3 id="配置路由">配置路由</h3>
<p>创建了隧道之后,我们还需要让它可以被访问。Cloudflare 支持将其部署到负载均衡器后端,或者通过 DNS 直接访问。这里只介绍后者的使用方法。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>cloudflared tunnel route dns <span style="color:#f92672">[</span>名字或者 UUID<span style="color:#f92672">]</span> <span style="color:#f92672">[</span>想要绑定到的域名或其二级域名<span style="color:#f92672">]</span>
</span></span></code></pre></div><p>你会发现这个域名被设置了一个指向 [UUID].cfargotunnel.com 的 CNAME 记录,并且通过 Cloudflare 进行代理(即橙云)。</p>
<h3 id="范例">范例</h3>
<p>例如,创建一条隧道,设置隧道名字为 twor.me,并将其绑定到 paste.twor.me:</p>
<ol>
<li>运行 cloudflare tunnel login,并在网页中授权 twor.me</li>
<li>运行 cloudflare tunnel create twor.me ,创建一个名为twor.me的隧道,隧道名可以随意</li>
<li>运行 cloudflared tunnel route dns twor.me paste.twor.me ,配置路由</li>
</ol>
<h3 id="其他">其他</h3>
<p>cloudflared &ndash;h</p>
</description>
</item>
<item>
<title>PHP转GO</title>
<link>https://twor.me/posts/php_to_go/</link>
<pubDate>Wed, 16 Nov 2022 15:59:34 +0800</pubDate>
<guid>https://twor.me/posts/php_to_go/</guid>
<description><p>最近在转语言,想从一名 PHPer 转成 Gopher,感觉我长时间搞 PHP,很多思想转不过来(究其原因还是太菜了)
今天就说说两者之间相似之处,亦或是不同的地方,说的对与不对完全是自己的理解
那么首先从依赖管理说起吧,我们知道 PHP 的依赖管理是 Composer。而 Go 目前大致差不多是 go mod 了,至于以前的 vendor 或者其他就不学也罢吧。
这里仅仅是说下两者的区别,至于更多高级用法,还是自己去看各自的依赖管理吧,这两个东西,拿出来讲 我觉得内容也不少,也是一个很重要的部分。有时间的话就再写一篇文章出来&hellip;.</p>
<h3 id="依赖管理">依赖管理</h3>
<h4 id="安装">安装</h4>
<p>在 PHP 中我们安装一个组件是 composer require xxx/xxx , 例如我们安装 超哥的 EasyWecaht</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>composer require w7corp/easywechat
</span></span></code></pre></div><p>而在 Go 中 我们使用 go get -u xxx, 例如安装 GORM</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go get gorm.io/gorm
</span></span></code></pre></div><h4 id="更新">更新</h4>
<p>使用第三方包,假设需要更新,在 PHP 中我们可以使用 composer update xxx</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>composer update w7corp/easywechat
</span></span></code></pre></div><p>Go 的话还是 go get 指定一个 -u 参数即可</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go get -u gorm.io/gorm
</span></span></code></pre></div><p>理论上更新的话需要慎重一些,下版本更新无所谓</p>
<h4 id="清理缓存">清理缓存</h4>
<p>在装这些依赖包的时候有时候会遇到各种稀奇古怪的问题,怎么办呢,问题有很多,但是很多时候清除一下缓存就好使了。
在 PHP 中 清除 composer 缓存,使用 clear-cache</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>composer clear-cache
</span></span></code></pre></div><p>Go 的话</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go clean --modcache
</span></span></code></pre></div><h4 id="自动加载更新依赖">自动加载更新依赖</h4>
<p>PHP</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>composer dump-autoload
</span></span></code></pre></div><p>Go go mod tidy 会自动更新当前 module 的依赖关系</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go mod tidy
</span></span></code></pre></div><h3 id="代理镜像">代理、镜像</h3>
<p>众所周知,我们在安装这些依赖的时候很大原因安装不上就是因为有堵墙。所以需要配置镜像,以便于加速下载
PHP 设置镜像,目前最好用的无非就是阿里云了,虽然不定时抽风。另外还有 华为、腾讯、安畅等镜像,这些我只有在阿里云抽风的情况下做个备选方案。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
</span></span></code></pre></div><p>Go 也有一些镜像,比如七牛、阿里等</p>
<h4 id="启用-go-modules-功能">启用 Go Modules 功能</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go env -w GO111MODULE<span style="color:#f92672">=</span>on
</span></span></code></pre></div><h4 id="配置-goproxy-环境变量以下三选一">配置 GOPROXY 环境变量,以下三选一</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e">#七牛 CDN</span>
</span></span><span style="display:flex;"><span>go env -w GOPROXY<span style="color:#f92672">=</span>https://goproxy.cn,direct
</span></span><span style="display:flex;"><span><span style="color:#75715e">#阿里云</span>
</span></span><span style="display:flex;"><span>go env -w GOPROXY<span style="color:#f92672">=</span>https://mirrors.aliyun.com/goproxy/,direct
</span></span><span style="display:flex;"><span><span style="color:#75715e">#官方</span>
</span></span><span style="display:flex;"><span>go env -w GOPROXY<span style="color:#f92672">=</span>https://goproxy.io,direct
</span></span></code></pre></div><h3 id="数组">数组</h3>
<p>在 PHP 中 数组即 Array,可以存储几乎任意类型,即使他们直接数据类型都不相同也无妨
例如:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$array <span style="color:#f92672">=</span> [<span style="color:#ae81ff">1</span>,<span style="color:#ae81ff">2</span>,<span style="color:#ae81ff">3</span>,<span style="color:#ae81ff">4</span>,<span style="color:#ae81ff">5</span>,<span style="color:#e6db74">&#39;A&#39;</span>,<span style="color:#e6db74">&#39;B&#39;</span>,<span style="color:#e6db74">&#39;c&#39;</span>,<span style="color:#e6db74">&#34;hello 你好&#34;</span>,<span style="color:#ae81ff">34.56</span>,<span style="color:#66d9ef">true</span>];
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">print_r</span>($array);
</span></span></code></pre></div><p>而在 Go 语言中数组则有很大的不同,首先必须申明数组长度、其次必须指明类型,只能赋值实现申明好的类型。例如:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#a6e22e">arr</span> <span style="color:#f92672">:=</span> [<span style="color:#ae81ff">5</span>]<span style="color:#66d9ef">int</span>{<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">3</span>, <span style="color:#ae81ff">4</span>, <span style="color:#ae81ff">5</span>}
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">arr</span>)
</span></span></code></pre></div><p>而如果你多添加了元素这在 Go 中是不允许的。以下方式不允许,且编译都不会通过</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#a6e22e">arr</span> <span style="color:#f92672">:=</span> [<span style="color:#ae81ff">5</span>]<span style="color:#66d9ef">int</span>{<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">3</span>, <span style="color:#ae81ff">4</span>, <span style="color:#ae81ff">5</span>, <span style="color:#ae81ff">6</span>}
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">arr</span>)
</span></span><span style="display:flex;"><span><span style="color:#75715e">// array index 5 out of bounds [0:5]
</span></span></span></code></pre></div><p>如果给定的元素不够事先申明的长度,那么默认会是当前类型的零值,例如 int 的零值是 0</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#a6e22e">arr</span> <span style="color:#f92672">:=</span> [<span style="color:#ae81ff">5</span>]<span style="color:#66d9ef">int</span>{<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">3</span>, <span style="color:#ae81ff">4</span>}
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">arr</span>)
</span></span><span style="display:flex;"><span><span style="color:#75715e">// [1 2 3 4 0]
</span></span></span></code></pre></div><p>当然如果你赋值的是其他类型 ,这在 Go 中也是行不通的</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#a6e22e">arr</span> <span style="color:#f92672">:=</span> [<span style="color:#ae81ff">5</span>]<span style="color:#66d9ef">int</span>{<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>, <span style="color:#e6db74">&#34;string&#34;</span>, <span style="color:#ae81ff">3</span>, <span style="color:#ae81ff">4</span>}
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">arr</span>)
</span></span><span style="display:flex;"><span><span style="color:#75715e">// cannot use &#34;string&#34; (type untyped string) as type int in array literal
</span></span></span></code></pre></div><p>在 Go 这一强类型中,必须事先申明类型,那么申明了类型就代表以后只允许这一类型的赋值。其他类型赋值则不允许。如果事先没申明 那么采用简短申明 ,Go 则会进行类型推断,同理也是 后续也只能赋值这一种类型</p>
<h3 id="值类型--引用类型">值类型 &amp; 引用类型</h3>
<p>在 PHP 中值类型包括:bool、int、string、float、以及 复杂数据类型 array 都是值类型
PHP 的对象则为引用类型:
例如:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Person</span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> $name;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">getName</span>()
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span>;
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">setName</span>($name)<span style="color:#f92672">:</span> <span style="color:#a6e22e">void</span>
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span> <span style="color:#f92672">=</span> $name;
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$p1 <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">Person</span>();
</span></span><span style="display:flex;"><span>$p1<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">setName</span>(<span style="color:#e6db74">&#34;php&#34;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$p2 <span style="color:#f92672">=</span> $p1;
</span></span><span style="display:flex;"><span>$p2<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">setName</span>(<span style="color:#e6db74">&#34;go&#34;</span>);
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">var_dump</span>($p1);
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">var_dump</span>($p2);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">var_dump</span>($p1 <span style="color:#f92672">===</span> $p2);
</span></span></code></pre></div><p>可以猜想一下以上内容会输出啥?</p>
<pre tabindex="0"><code class="language-obj" data-lang="obj">object(Person)#1 (1) {
[&#34;name&#34;]=&gt;
string(2) &#34;go&#34;
}
object(Person)#1 (1) {
[&#34;name&#34;]=&gt;
string(2) &#34;go&#34;
}
bool(true)
</code></pre><p>其实如果用 PHPStorm 最后的 $p1 === $p2 已经给出警告了,Condition is always &rsquo;true&rsquo; because &lsquo;$p2&rsquo; is evaluated at this point
那么,如何解决此类型的问题呢?如果想得到对象的一个副本(将复制旧变量的所有属性), 在 PHP 中我们可以使用 clone</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Person</span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> $name;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">getName</span>()
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span>;
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">setName</span>($name)<span style="color:#f92672">:</span> <span style="color:#a6e22e">void</span>
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span> <span style="color:#f92672">=</span> $name;
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$p1 <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">Person</span>();
</span></span><span style="display:flex;"><span>$p1<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">setName</span>(<span style="color:#e6db74">&#34;php&#34;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$p2 <span style="color:#f92672">=</span> <span style="color:#66d9ef">clone</span> $p1;
</span></span><span style="display:flex;"><span>$p2<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">setName</span>(<span style="color:#e6db74">&#34;go&#34;</span>);
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">var_dump</span>($p1);
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">var_dump</span>($p2);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">var_dump</span>($p1 <span style="color:#f92672">===</span> $p2);
</span></span></code></pre></div><p>同样的内容,我们把 $p2 = $p1; 改成 $p2 = clone $p1; 即可解决此类问题,输出会变成以下内容</p>
<pre tabindex="0"><code class="language-obj" data-lang="obj">object(Person)#1 (1) {
[&#34;name&#34;]=&gt;
string(3) &#34;php&#34;
}
object(Person)#2 (1) {
[&#34;name&#34;]=&gt;
string(2) &#34;go&#34;
}
bool(false)
</code></pre><p>Go 语言值类型包括 int 系列、float 系列、bool、string、数组、结构体(struct)
引用类型包括:指针、slice 切片、map、管道 chan、interface
上面给出了,Go 语言值类型、引用类型,其实在 Go 语言面向对象的概念微乎其微,但是我们可以采用 struct 结构体来对标 PHP 中的 class</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Person</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Name</span> <span style="color:#66d9ef">string</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">p1</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">Person</span>{}
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">p1</span>.<span style="color:#a6e22e">Name</span> = <span style="color:#e6db74">&#34;John&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">p2</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">p1</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">p2</span>.<span style="color:#a6e22e">Name</span> = <span style="color:#e6db74">&#34;Jane&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;p1:%+v p2:%+v\n&#34;</span>, <span style="color:#a6e22e">p1</span>, <span style="color:#a6e22e">p2</span>)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>猜想一下 以上内容会出啥?</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>p1:{Name:John} p2:{Name:Jane}
</span></span></code></pre></div><p>如果将它 变成引用类型怎么办呢?答案是使用指针。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Person</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Name</span> <span style="color:#66d9ef">string</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">p1</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">Person</span>{}
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">p1</span>.<span style="color:#a6e22e">Name</span> = <span style="color:#e6db74">&#34;John&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">p2</span> <span style="color:#f92672">:=</span> <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">p1</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">p2</span>.<span style="color:#a6e22e">Name</span> = <span style="color:#e6db74">&#34;Jane&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;p1:%+v p2:%+v\n&#34;</span>, <span style="color:#a6e22e">p1</span>, <span style="color:#a6e22e">p2</span>)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>只更改了 p2 := p1 为 p2 := &amp;p1, 加了一个 &amp; 符号,那么就会输出如下内容</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>p1:{Name:Jane} p2:&amp;{Name:Jane}
</span></span></code></pre></div><p>把上面的例子简单改造一下,改造成否和面向对象的方式,比如我们更改 Name 只能通过 setName,获取 Name 是 getName</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Person</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Name</span> <span style="color:#66d9ef">string</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">p</span> <span style="color:#a6e22e">Person</span>) <span style="color:#a6e22e">getName</span>() <span style="color:#66d9ef">string</span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">p</span>.<span style="color:#a6e22e">Name</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">p</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">Person</span>) <span style="color:#a6e22e">setName</span>(<span style="color:#a6e22e">name</span> <span style="color:#66d9ef">string</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">p</span>.<span style="color:#a6e22e">Name</span> = <span style="color:#a6e22e">name</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">p1</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">Person</span>{}
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">p1</span>.<span style="color:#a6e22e">setName</span>(<span style="color:#e6db74">&#34;John&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">p2</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">p1</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">p2</span>.<span style="color:#a6e22e">setName</span>(<span style="color:#e6db74">&#34;Jane&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">p1</span>.<span style="color:#a6e22e">getName</span>())
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">p2</span>.<span style="color:#a6e22e">getName</span>())
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>同理如果 将 p1 赋值 给 p2 还是使用指针 p2 := &amp;p1</p>
<h3 id="接口-interface">接口 Interface</h3>
<p>PHP 如果实现接口则需要定义一个 接口 类,然后子类中使用关键字 implements 来实现该接口的 所有方法。注意是 所有,例如我们有一个接口,暂定为 A,该接口规定了两个方法,foo() 以及 bar()</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">A</span>{
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">foo</span>($foo);
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">bar</span>($bar);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>继续用上面的 Person 类来实现这个接口</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Person</span> <span style="color:#66d9ef">implements</span> <span style="color:#a6e22e">A</span> {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> $name;
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">getName</span>()
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span>;
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">setName</span>($name)<span style="color:#f92672">:</span> <span style="color:#a6e22e">void</span>
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span> <span style="color:#f92672">=</span> $name;
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>而如果我们使用了 implements A ,但是并没有实现其中的两个方法,则在运行的时候 PHP 会报出致命性错误</p>
<blockquote>
<p>PHP Fatal error: Class Person contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (A::foo, A::bar)
Fatal error: Class Person contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (A::foo, A::bar)</p>
</blockquote>
<p>可以看到必须同时实现两个方法</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">A</span>{
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">foo</span>($foo);
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">bar</span>($bar);
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Person</span> <span style="color:#66d9ef">implements</span> <span style="color:#a6e22e">A</span> {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> $name;
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">getName</span>()
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span>;
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">setName</span>($name)<span style="color:#f92672">:</span> <span style="color:#a6e22e">void</span>
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span> <span style="color:#f92672">=</span> $name;
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">foo</span>($foo)
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// TODO: Implement foo() method.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">return</span> $foo;
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">bar</span>($bar)
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// TODO: Implement bar() method.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">return</span> $bar;
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$p1 <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">Person</span>();
</span></span><span style="display:flex;"><span>$p1<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">setName</span>(<span style="color:#e6db74">&#34;php&#34;</span>);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">echo</span> $p1<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">foo</span>(<span style="color:#e6db74">&#34;php&#34;</span>),$p1<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">bar</span>(<span style="color:#ae81ff">123</span>);
</span></span></code></pre></div><p>这两个方法接收任意类型的数据类型,但是在 Go 中必须指明类型,但是 PHP 7 ,我们同样可以强制参数为具体的类型,例如 foo(int $foo) , 表示只允许接收 int 类型,同样如果给定的不是 int 运行时则会报错
而 在 Go 语言中 则不需要 使用什么 implements 等关键字了,在 Go 语言中接口是隐式的,对于一个接口类型,我们并不需要知道它实现了哪个接口,只要它实现了接口中的所有方法即可</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">A</span> <span style="color:#66d9ef">interface</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">foo</span>(<span style="color:#a6e22e">foo</span> <span style="color:#66d9ef">string</span>) <span style="color:#66d9ef">string</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">bar</span>(<span style="color:#a6e22e">bar</span> <span style="color:#66d9ef">int</span>) <span style="color:#66d9ef">int</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Person</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Name</span> <span style="color:#66d9ef">string</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">p</span> <span style="color:#a6e22e">Person</span>) <span style="color:#a6e22e">foo</span>(<span style="color:#a6e22e">foo</span> <span style="color:#66d9ef">string</span>) <span style="color:#66d9ef">string</span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Sprintf</span>(<span style="color:#e6db74">&#34;%s %s&#34;</span>, <span style="color:#a6e22e">foo</span>, <span style="color:#a6e22e">p</span>.<span style="color:#a6e22e">Name</span>)
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">p</span> <span style="color:#a6e22e">Person</span>) <span style="color:#a6e22e">bar</span>(<span style="color:#a6e22e">bar</span> <span style="color:#66d9ef">int</span>) <span style="color:#66d9ef">int</span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">bar</span> <span style="color:#f92672">+</span> <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">a</span> <span style="color:#a6e22e">A</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">a</span> = <span style="color:#a6e22e">Person</span>{<span style="color:#e6db74">&#34;Bob&#34;</span>}
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">a</span>.<span style="color:#a6e22e">foo</span>(<span style="color:#e6db74">&#34;Hello&#34;</span>))
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">a</span>.<span style="color:#a6e22e">bar</span>(<span style="color:#ae81ff">1</span>))
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="结构体初始化">结构体初始化</h3>
<p>PHP 有些钩子函数,例如:__construct 用与初始化</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Person</span>{
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> $name;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> __construct($name)
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span> <span style="color:#f92672">=</span> $name;
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$p1 <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">Person</span>(<span style="color:#e6db74">&#34;John&#34;</span>);
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">var_dump</span>($p1);
</span></span></code></pre></div><p>在 Go 则没有这类方法,大家差不多都是定义一个 func 函数,函数名为 NewXXX 开头。例如:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Person</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Name</span> <span style="color:#66d9ef">string</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">NewPerson</span>(<span style="color:#a6e22e">name</span> <span style="color:#66d9ef">string</span>) <span style="color:#f92672">*</span><span style="color:#a6e22e">Person</span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">Person</span>{<span style="color:#a6e22e">Name</span>: <span style="color:#a6e22e">name</span>}
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">person</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">NewPerson</span>(<span style="color:#e6db74">&#34;John&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">person</span>.<span style="color:#a6e22e">Name</span>)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="异常处理">异常处理</h3>
<p>PHP 中处理异常我们可以采用 try catch 进行捕获</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Test</span>{
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">inverse</span>($a,$b) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#f92672">!</span>$b) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">throw</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">Exception</span>(<span style="color:#e6db74">&#39;Division by zero.&#39;</span>);
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> $a <span style="color:#f92672">/</span>$b;
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$t <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">Test</span>();
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">try</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">var_dump</span>($t<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">inverse</span>(<span style="color:#ae81ff">4</span>, <span style="color:#ae81ff">5</span>));
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">var_dump</span>($t<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">inverse</span>(<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">0</span>));
</span></span><span style="display:flex;"><span>} <span style="color:#66d9ef">catch</span> (<span style="color:#a6e22e">Exception</span> $e) {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">var_dump</span>($e<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">getMessage</span>());
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">var_dump</span>(<span style="color:#e6db74">&#34;hello&#34;</span>);
</span></span></code></pre></div><p>则会输出</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>float(0.8)
</span></span><span style="display:flex;"><span>string(17) &#34;Division by zero.&#34;
</span></span><span style="display:flex;"><span>string(5) &#34;hello&#34;
</span></span></code></pre></div><p>可以看到,$t-&gt;inverse (1, 0) ,我们捕获了异常,输出了错误,但是并不影响后续的执行
但是在 Go 中并没有异常处理的方式。错误只能我们进行手动处理,大概可以看到 满屏的 if err != nil 例如:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">inverse</span>(<span style="color:#a6e22e">a</span>, <span style="color:#a6e22e">b</span> <span style="color:#66d9ef">int</span>) (<span style="color:#66d9ef">int</span>, <span style="color:#66d9ef">error</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">b</span> <span style="color:#f92672">==</span> <span style="color:#ae81ff">0</span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>, <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;b cannot be zero&#34;</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">a</span> <span style="color:#f92672">/</span> <span style="color:#a6e22e">b</span>, <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">i</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">inverse</span>(<span style="color:#ae81ff">6</span>, <span style="color:#ae81ff">3</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;Error: %v\n&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">i</span>)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>还有就是 我们的程序可能引发 panic, 一旦遇到 panic,我们的程序可能就会立马终止了,这时我们可以使用 defer + recover() 进行捕获。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">inverse</span>(<span style="color:#a6e22e">a</span>, <span style="color:#a6e22e">b</span> <span style="color:#66d9ef">int</span>) (<span style="color:#66d9ef">int</span>, <span style="color:#66d9ef">error</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">defer</span> <span style="color:#66d9ef">func</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> recover(); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;Panic recover, Err =&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }()
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">a</span> <span style="color:#f92672">/</span> <span style="color:#a6e22e">b</span>, <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">inverse</span>(<span style="color:#ae81ff">10</span>, <span style="color:#ae81ff">5</span>))
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">inverse</span>(<span style="color:#ae81ff">10</span>, <span style="color:#ae81ff">0</span>))
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">inverse</span>(<span style="color:#ae81ff">10</span>, <span style="color:#ae81ff">2</span>))
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;Over&#34;</span>)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>输出的内容如下:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>2 &lt;nil&gt;
</span></span><span style="display:flex;"><span>Panic recover, Err = runtime error: integer divide by zero
</span></span><span style="display:flex;"><span>0 &lt;nil&gt;
</span></span><span style="display:flex;"><span>5 &lt;nil&gt;
</span></span><span style="display:flex;"><span>Over
</span></span></code></pre></div><h3 id="json-处理">JSON 处理</h3>
<p>在 PHP 中几乎所有的东西 都是 array 一把锁,md 在 Go 中又分数组、切片、map 等等&hellip;..
在 PHP 中 array 和 json 相互转换是一件非常 easy 的事,我们可以使用 json_encode 以及 json_decode
例如 将数组转为 json</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$array <span style="color:#f92672">=</span> [<span style="color:#e6db74">&#34;name&#34;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#34;hedeqiang&#34;</span>,<span style="color:#e6db74">&#34;age&#34;</span><span style="color:#f92672">=&gt;</span><span style="color:#ae81ff">18</span>];
</span></span><span style="display:flex;"><span>$json <span style="color:#f92672">=</span> <span style="color:#a6e22e">json_encode</span>($array);
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">var_dump</span>($json); <span style="color:#75715e">// string(29) &#34;{&#34;name&#34;:&#34;hedeqiang&#34;,&#34;age&#34;:18}&#34;
</span></span></span></code></pre></div><p>将 json 转为 数组</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$array <span style="color:#f92672">=</span> [<span style="color:#e6db74">&#34;name&#34;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#34;hedeqiang&#34;</span>,<span style="color:#e6db74">&#34;age&#34;</span><span style="color:#f92672">=&gt;</span><span style="color:#ae81ff">18</span>];
</span></span><span style="display:flex;"><span>$json <span style="color:#f92672">=</span> <span style="color:#a6e22e">json_encode</span>($array);
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">var_dump</span>(<span style="color:#a6e22e">json_decode</span>($json,<span style="color:#66d9ef">true</span>));
</span></span></code></pre></div><p>即可转为数组:</p>
<pre tabindex="0"><code class="language-array" data-lang="array">array(2) {
[&#34;name&#34;]=&gt;
string(9) &#34;hedeqiang&#34;
[&#34;age&#34;]=&gt;
int(18)
}
</code></pre><p>转为对象呢,将 json_decode 第二个参数设置为 true</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$array <span style="color:#f92672">=</span> [<span style="color:#e6db74">&#34;name&#34;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#34;hedeqiang&#34;</span>,<span style="color:#e6db74">&#34;age&#34;</span><span style="color:#f92672">=&gt;</span><span style="color:#ae81ff">18</span>];
</span></span><span style="display:flex;"><span>$json <span style="color:#f92672">=</span> <span style="color:#a6e22e">json_encode</span>($array);
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">var_dump</span>(<span style="color:#a6e22e">json_decode</span>($json));
</span></span></code></pre></div><p>即可转为对象:</p>
<pre tabindex="0"><code class="language-obj" data-lang="obj">object(stdClass)#1 (2) {
[&#34;name&#34;]=&gt;
string(9) &#34;hedeqiang&#34;
[&#34;age&#34;]=&gt;
int(18)
}
</code></pre><p>而在 Go 中似乎就没这么方便了,需要配合 struct 再结合 json 包的 Marshal 以及 Unmarshal 来进行处理
结构体序列化成 json:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> (
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;encoding/json&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Person</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Name</span> <span style="color:#66d9ef">string</span> <span style="color:#e6db74">`json:&#34;name&#34;`</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Age</span> <span style="color:#66d9ef">int</span> <span style="color:#e6db74">`json:&#34;age&#34;`</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">p</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">Person</span>{<span style="color:#a6e22e">Name</span>: <span style="color:#e6db74">&#34;John&#34;</span>, <span style="color:#a6e22e">Age</span>: <span style="color:#ae81ff">30</span>}
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">b</span>, <span style="color:#a6e22e">_</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">json</span>.<span style="color:#a6e22e">Marshal</span>(<span style="color:#a6e22e">p</span>)
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(string(<span style="color:#a6e22e">b</span>))
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>json 转化为 结构体</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> (
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;encoding/json&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Person</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Name</span> <span style="color:#66d9ef">string</span> <span style="color:#e6db74">`json:&#34;name&#34;`</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Age</span> <span style="color:#66d9ef">int</span> <span style="color:#e6db74">`json:&#34;age&#34;`</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">jsonString</span> <span style="color:#f92672">:=</span> <span style="color:#e6db74">`{&#34;name&#34;:&#34;hedeqiang&#34;,&#34;age&#34;:18}`</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">person</span> <span style="color:#a6e22e">Person</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">json</span>.<span style="color:#a6e22e">Unmarshal</span>([]byte(<span style="color:#a6e22e">jsonString</span>), <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">person</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;%+v\n&#34;</span>, <span style="color:#a6e22e">person</span>)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>当然 json 包很强大,不仅局限于 结构体
好了 ,这次就先到这吧,感觉还有很多,等着有时间再介绍吧&hellip;&hellip;(不知道下次啥时候..)</p>
</description>
</item>
<item>
<title>go 安装与配置和常用命令</title>
<link>https://twor.me/posts/go_note/</link>
<pubDate>Sat, 18 Jun 2022 17:52:20 +0800</pubDate>
<guid>https://twor.me/posts/go_note/</guid>
<description><h1 id="go-安装与配置">go 安装与配置</h1>
<h3 id="安装">安装</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo pacman -S go
</span></span></code></pre></div><p><em>也可以使用<a href="https://github.com/owenthereal/goup">goup</a>安装器安装</em></p>
<h3 id="配置">配置</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e">#编辑 env 文件</span>
</span></span><span style="display:flex;"><span>vim .config/go/env
</span></span></code></pre></div><p>添加下面内容</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-env" data-lang="env"><span style="display:flex;"><span>GO111MODULE<span style="color:#f92672">=</span>on <span style="color:#75715e">#开启gomod</span>
</span></span><span style="display:flex;"><span>GOPATH<span style="color:#f92672">=</span>/angus/Go <span style="color:#75715e">#设置gopath</span>
</span></span><span style="display:flex;"><span>GOPROXY<span style="color:#f92672">=</span>https://goproxy.cn,direct <span style="color:#75715e">#设置goproxy(代理源)</span>
</span></span></code></pre></div><p>查看环境变量</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go env
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 查看gomod gopath goproxy是否设置正确</span>
</span></span></code></pre></div><h4 id="gopath">gopath</h4>
<p>GOPATH 是 Go语言中使用的一个环境变量,它使用绝对路径提供项目的工作目录,所下载的包都保留在gopath指向的目录</p>
<h4 id="goproxy源">goproxy源</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># 1. 七牛 CDN</span>
</span></span><span style="display:flex;"><span>go env -w GOPROXY<span style="color:#f92672">=</span>https://goproxy.cn,direct
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 2. 阿里云</span>
</span></span><span style="display:flex;"><span>go env -w GOPROXY<span style="color:#f92672">=</span>https://mirrors.aliyun.com/goproxy/,direct
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 3. 官方</span>
</span></span><span style="display:flex;"><span>go env -w GOPROXY<span style="color:#f92672">=</span>https://goproxy.io,direct
</span></span></code></pre></div><h3 id="常用命令">常用命令</h3>
<ul>
<li>包管理</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go mod init <span style="color:#75715e"># 初始化包管理配置,这一步会在module根目录下生成go.mod文件</span>
</span></span><span style="display:flex;"><span>go mod tidy <span style="color:#75715e"># 更新包管理配置go.mod(去掉无用module, 新增必要module)</span>
</span></span><span style="display:flex;"><span>go get -u github.com/hashicorp/memberlist <span style="color:#75715e"># 添加包依赖</span>
</span></span><span style="display:flex;"><span>go mod edit -replace github.com/hashicorp/memberlist <span style="color:#f92672">=</span>&gt; github.com/pilosa/[email protected] <span style="color:#75715e"># 替换依赖库。但是module中的代码扔可以原依赖库的方式使用新依赖库。</span>
</span></span></code></pre></div><ul>
<li>编译</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go build <span style="color:#75715e"># 编译当前目录所在package</span>
</span></span><span style="display:flex;"><span>go build -o &lt;bin&gt; main.go <span style="color:#75715e"># 编译代码并指定输出二进制文件</span>
</span></span><span style="display:flex;"><span>go build -gcflags <span style="color:#e6db74">&#34;-N -l&#34;</span> main.go <span style="color:#75715e"># 编译时关闭内联优化</span>
</span></span><span style="display:flex;"><span>go clean <span style="color:#75715e">#删除编译生成的可执行文件</span>
</span></span></code></pre></div><ul>
<li>测试</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># 读取源码目录下面名为 *_test.go 的文件,生成并运行测试用的可执行文件</span>
</span></span><span style="display:flex;"><span>go test ./... <span style="color:#75715e"># 运行module下所有单测。一个module对应一个go.mod文件</span>
</span></span><span style="display:flex;"><span>go test . <span style="color:#75715e"># 运行package下所有单测。一个package对应一个目录</span>
</span></span><span style="display:flex;"><span>go test -v . <span style="color:#75715e"># 添加verbose信息,会输出日志等信息</span>
</span></span><span style="display:flex;"><span>go test -run<span style="color:#f92672">=</span><span style="color:#e6db74">`</span>&lt;regexp&gt; <span style="color:#e6db74">`</span>. <span style="color:#75715e"># 运行符合正则表达式的的单测</span>
</span></span><span style="display:flex;"><span>go test -bench -run<span style="color:#f92672">=</span>None <span style="color:#75715e"># 运行基准测试</span>
</span></span></code></pre></div><ul>
<li>调试</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># 需要安装dlv go install github.com/go-delve/delve/cmd/dlv@latest</span>
</span></span><span style="display:flex;"><span>dlv exec &lt;bin&gt; -- arg1 arg2 ... <span style="color:#75715e"># 调试运行binary文件</span>
</span></span><span style="display:flex;"><span>dlv test . <span style="color:#75715e"># 调试当前module的测试代码</span>
</span></span><span style="display:flex;"><span>dlv attach &lt;pid&gt; <span style="color:#75715e"># 调试正在运行的进程</span>
</span></span><span style="display:flex;"><span>dlv core <span style="color:#e6db74">`</span>&lt;bin&gt;<span style="color:#e6db74">`</span> <span style="color:#e6db74">`</span>&lt;core&gt;<span style="color:#e6db74">`</span> <span style="color:#75715e"># 调试core文件</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 远程调试</span>
</span></span><span style="display:flex;"><span>dlv attach &lt;pid&gt; --headless --api-version<span style="color:#f92672">=</span><span style="color:#ae81ff">2</span> --log --listen<span style="color:#f92672">=</span>:8181 <span style="color:#75715e">## server端</span>
</span></span><span style="display:flex;"><span>dlv connect &lt;server_host&gt;:8181 <span style="color:#75715e">## client端</span>
</span></span></code></pre></div><ul>
<li>调优</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go tool pprof http://host:port/debug/pprof/profile <span style="color:#75715e"># 通过net/http/pprof采集profile并下载到本地</span>
</span></span><span style="display:flex;"><span>go tool pprof -&lt;host&gt;:&lt;port&gt; &lt;profile_file&gt; <span style="color:#75715e"># 通过浏览器查看profile.</span>
</span></span></code></pre></div></description>
</item>
<item>
<title>我的 Linux 软件清单</title>
<link>https://twor.me/posts/linux_apps/</link>
<pubDate>Sun, 08 May 2022 16:29:35 +0800</pubDate>
<guid>https://twor.me/posts/linux_apps/</guid>
<description><h4 id="nautilus">Nautilus</h4>
<p>它是GNOME的文件管理器。比较好用,简洁图形化操作</p>
<p><a href="https://github.com/GNOME/nautilus"><img src="https://gh-card.dev/repos/GNOME/nautilus.png" alt="GNOME/nautilus - GitHub"></a></p>
<h4 id="ranger">ranger</h4>
<p>Ranger是具有VI键绑定的控制台文件管理器</p>
<p><a href="https://github.com/GNOME/nautilus"><img src="https://gh-card.dev/repos/GNOME/nautilus.png" alt="GNOME/nautilus - GitHub"></a></p>
<h4 id="obs-studio">obs-studio</h4>
<p>OBS Studio是为高效捕获,合成,编码,记录和流传输视频内容而设计的软件。</p>
<p><a href="https://github.com/obsproject/obs-studio"><img src="https://gh-card.dev/repos/obsproject/obs-studio.png" alt="obsproject/obs-studio - GitHub"></a></p>
<h4 id="feh">feh</h4>
<p>快速轻巧的图像查看器</p>
<p><a href="https://github.com/derf/feh"><img src="https://gh-card.dev/repos/derf/feh.png" alt="derf/feh - GitHub"></a></p>
<h4 id="vscode">vscode</h4>
<p>微软出品的代码编辑器</p>
<p><a href="https://github.com/microsoft/vscode"><img src="https://gh-card.dev/repos/microsoft/vscode.png" alt="microsoft/vscode - GitHub"></a></p>
<h4 id="simplenote">simplenote</h4>
<p>笔记本</p>
<p><a href="https://aur.archlinux.org/packages/notion-app/">https://aur.archlinux.org/packages/notion-app/</a></p>
<h4 id="ibus-rime">ibus-rime</h4>
<p>中文输入法</p>
<p><a href="https://github.com/rime/ibus-rime"><img src="https://gh-card.dev/repos/rime/ibus-rime.png" alt="rime/ibus-rime - GitHub"></a></p>
<h4 id="i3-gaps">i3-gaps</h4>
<p>平铺窗口管理器</p>
<p><a href="https://github.com/Airblader/i3"><img src="https://gh-card.dev/repos/Airblader/i3.png" alt="Airblader/i3 - GitHub"></a></p>
<h4 id="clash">clash</h4>
<p>代理/翻墙</p>
<p><a href="https://github.com/Dreamacro/clash"><img src="https://gh-card.dev/repos/Dreamacro/clash.png" alt="Dreamacro/clash - GitHub"></a></p>
<h4 id="mpv">mpv</h4>
<p>视频播放器</p>
<p><a href="https://github.com/mpv-player/mpv"><img src="https://gh-card.dev/repos/mpv-player/mpv.png" alt="mpv-player/mpv - GitHub"></a></p>
<h4 id="rofi">rofi</h4>
<p>Rofi:窗口切换器,应用程序启动器和dmenu替换</p>
<p><a href="https://github.com/davatorium/rofi"><img src="https://gh-card.dev/repos/davatorium/rofi.png" alt="davatorium/rofi - GitHub"></a></p>
<h4 id="dunst">dunst</h4>
<p>轻量级和可自定义的通知守护程序</p>
<p><a href="https://github.com/dunst-project/dunst"><img src="https://gh-card.dev/repos/dunst-project/dunst.png" alt="dunst-project/dunst - GitHub"></a></p>
<h4 id="indicator-stickynotes">indicator-stickynotes</h4>
<p>指标便利贴:适用于Ubuntu桌面的便利贴</p>
<p><a href="https://github.com/umangv/indicator-stickynotes"><img src="https://gh-card.dev/repos/umangv/indicator-stickynotes.png" alt="umangv/indicator-stickynotes - GitHub"></a></p>
<h4 id="drawing">drawing</h4>
<p>一个画图小工具</p>
<p><a href="https://github.com/maoschanz/drawing"><img src="https://gh-card.dev/repos/maoschanz/drawing.svg" alt="maoschanz/drawing - GitHub"></a></p>
<h4 id="kitty">kitty</h4>
<p>基于GPU的跨平台、快速、功能丰富的终端</p>
<p><a href="https://github.com/kovidgoyal/kitty"><img src="https://gh-card.dev/repos/kovidgoyal/kitty.png" alt="kovidgoyal/kitty - GitHub"></a></p>
<h4 id="zsh">zsh</h4>
<p>很好用的一个shll</p>
<p><a href="https://github.com/zsh-users/zsh"><img src="https://gh-card.dev/repos/zsh-users/zsh.png" alt="zsh-users/zsh - GitHub"></a></p>
<h4 id="zsh-snap">zsh-snap</h4>
<p>快速、易用的Zsh dotfiles 和插件工具,以及git repos</p>
<p><a href="https://github.com/marlonrichert/zsh-snap"><img src="https://gh-card.dev/repos/marlonrichert/zsh-snap.png" alt="marlonrichert/zsh-snap - GitHub"></a></p>
<h4 id="fzf">fzf</h4>
<p>命令行模糊查找器</p>
<p><a href="https://github.com/junegunn/fzf"><img src="https://gh-card.dev/repos/junegunn/fzf.png" alt="junegunn/fzf - GitHub"></a></p>
<h4 id="nordic-darker">Nordic-darker</h4>
<p>Gtk3.20 +主题</p>
<p><a href="https://github.com/EliverLara/Nordic"><img src="https://gh-card.dev/repos/EliverLara/Nordic.png" alt="EliverLara/Nordic - GitHub"></a></p>
<h4 id="epapirus">ePapirus</h4>
<p>Linux的Papirus图标主题</p>
<p><a href="https://github.com/PapirusDevelopmentTeam/papirus-icon-theme"><img src="https://gh-card.dev/repos/PapirusDevelopmentTeam/papirus-icon-theme.png" alt="PapirusDevelopmentTeam/papirus-icon-theme - GitHub"></a></p>
<h4 id="citrus-purple-dark">Citrus-purple-dark</h4>
<p>Linux桌面图标主题</p>
<p><a href="https://github.com/yeyushengfan258/Citrus-icon-theme"><img src="https://gh-card.dev/repos/yeyushengfan258/Citrus-icon-theme.png" alt="yeyushengfan258/Citrus-icon-theme - GitHub"></a></p>
<h4 id="cantarell">Cantarell</h4>
<p>很好看的字体</p>
<p><a href="https://github.com/GNOME/cantarell-fonts"><img src="https://gh-card.dev/repos/GNOME/cantarell-fonts.png" alt="GNOME/cantarell-fonts - GitHub"></a></p>
<h4 id="cascadia-code">Cascadia Code</h4>
<p>写代码和终端用的字体</p>
<p><a href="https://github.com/microsoft/cascadia-code"><img src="https://gh-card.dev/repos/microsoft/cascadia-code.png" alt="microsoft/cascadia-code - GitHub"></a></p>
<h4 id="polybar">polybar</h4>
<p>快速且易于使用的状态栏</p>
<p><a href="https://github.com/polybar/polybar"><img src="https://gh-card.dev/repos/polybar/polybar.png" alt="polybar/polybar - GitHub"></a></p>
<h4 id="picom">picom</h4>
<p>X11的窗口修改器</p>
<p><a href="https://github.com/yshui/picom"><img src="https://gh-card.dev/repos/yshui/picom.png" alt="yshui/picom - GitHub"></a></p>
<h4 id="lxappearance-gtk3">lxappearance-gtk3</h4>
<p>LXDE桌面的功能丰富的GTK +主题切换器</p>
<p><a href="https://www.archlinux.org/packages/community/x86_64/lxappearance/">https://www.archlinux.org/packages/community/x86_64/lxappearance/</a></p>
<h4 id="translate-shell">translate-shell</h4>
<p>终端翻译工具,可以发音</p>
<p><a href="https://github.com/soimort/translate-shell"><img src="https://gh-card.dev/repos/soimort/translate-shell.svg" alt="soimort/translate-shell - GitHub"></a></p>
<h4 id="scrcpy">scrcpy</h4>
<p>连接控制手机</p>
<p><a href="https://github.com/Genymobile/scrcpy"><img src="https://gh-card.dev/repos/Genymobile/scrcpy.svg" alt="Genymobile/scrcpy - GitHub"></a></p>
<h4 id="syncthing">syncthing</h4>
<p>文件同步</p>
<p><a href="https://github.com/syncthing/syncthing"><img src="https://gh-card.dev/repos/syncthing/syncthing.svg" alt="syncthing/syncthing - GitHub"></a></p>
<h4 id="gotohttp">gotohttp</h4>
<p>远程网页端控制</p>
<p><a href="https://gotohttp.com/">https://gotohttp.com/</a></p>
<h4 id="insomnia">insomnia</h4>
<p>api 调试</p>
<p><a href="https://insomnia.rest/">insomnia</a></p>
<h4 id="beekeeperstudio">beekeeperstudio</h4>
<p>数据库管理</p>
<p><a href="https://www.beekeeperstudio.io/">beekeeper studio</a></p>
<h4 id="flameshot">flameshot</h4>
<p>截图工具</p>
<p><a href="https://github.com/flameshot-org/flameshot"><img src="https://gh-card.dev/repos/flameshot-org/flameshot.png" alt="flameshot-org/flameshot - GitHub"></a></p>
</description>
</item>
<item>
<title>搭建自定义域名的本地HTTPS开发服务器</title>
<link>https://twor.me/posts/local_https/</link>
<pubDate>Mon, 18 Oct 2021 16:27:34 +0800</pubDate>
<guid>https://twor.me/posts/local_https/</guid>
<description><h3 id="mkcert简介">mkcert简介</h3>
<p><a href="https://links.jianshu.com/go?to=https%3A%2F%2Fgithub.com%2FFiloSottile%2Fmkcert">mkcert</a>是一个使用go语言编写的生成本地自签证书的小程序,具有跨平台,使用简单,支持多域名,自动信任CA等一系列方便的特性可供本地开发时快速创建https环境使用。</p>
<p>安装方式也非常简单,由于go语言的静态编译和跨平台的特性,官方提供各平台预编译的版本,直接下载到本地,给可执行权限(Linux/Unix需要)就可以了。下载地址:</p>
<p>项目地址:[<a href="https://github.com/FiloSottile/mkcert/releases/latest">https://github.com/FiloSottile/mkcert</a>](<a href="https://github.com/FiloSottile/mkcert/releases/latest">https://github.com/FiloSottile/mkcert</a>)</p>
<h3 id="安装mkcert">安装mkcert</h3>
<h3 id="macos"><strong>macOS</strong></h3>
<p>1. <a href="https://brew.sh/">Homebrew</a></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>brew install mkcert
</span></span><span style="display:flex;"><span>brew install nss <span style="color:#75715e"># if you use Firefox</span>
</span></span></code></pre></div><p>2. <a href="https://www.macports.org/">MacPorts</a>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo port selfupdate
</span></span><span style="display:flex;"><span>sudo port install mkcert
</span></span><span style="display:flex;"><span>sudo port install nss <span style="color:#75715e"># if you use Firefox</span>
</span></span></code></pre></div><h3 id="linux"><strong>Linux</strong></h3>
<h4 id="首先安装certutil">首先安装 <code>certutil</code>.</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo apt install libnss3-tools
</span></span><span style="display:flex;"><span> -or-
</span></span><span style="display:flex;"><span>sudo yum install nss-tools
</span></span><span style="display:flex;"><span> -or-
</span></span><span style="display:flex;"><span>sudo pacman -S nss
</span></span><span style="display:flex;"><span> -or-
</span></span><span style="display:flex;"><span>sudo zypper install mozilla-nss-tools
</span></span></code></pre></div><h4 id="然后安装-mkcerthttpsgithubcomfilosottilemkcert">然后安装 <a href="https://github.com/FiloSottile/mkcert">mkcert</a></h4>
<p><a href="http://linuxbrew.sh/">Linuxbrew</a></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>brew install mkcert
</span></span></code></pre></div><p>或者自己编译 (requires Go 1.13+)</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>git clone https://github.com/FiloSottile/mkcert <span style="color:#f92672">&amp;&amp;</span> cd mkcert
</span></span><span style="display:flex;"><span>go build -ldflags <span style="color:#e6db74">&#34;-X main.Version=</span><span style="color:#66d9ef">$(</span>git describe --tags<span style="color:#66d9ef">)</span><span style="color:#e6db74">&#34;</span>
</span></span></code></pre></div><p>也可以下载编译好的包 <a href="https://github.com/FiloSottile/mkcert/releases">the pre-built binaries</a>.</p>
<p>Arch Linux , <code>[mkcert](https://www.archlinux.org/packages/community/x86_64/mkcert/)</code> </p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo pacman -Syu mkcert
</span></span></code></pre></div><h3 id="windows"><strong>Windows</strong></h3>
<p>1.<a href="https://chocolatey.org/">Chocolatey</a></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>choco install mkcert
</span></span></code></pre></div><ol start="2">
<li>Scoop</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>scoop bucket add extras
</span></span><span style="display:flex;"><span>scoop install mkcert
</span></span></code></pre></div><p>也可以下载编译好的包 <a href="https://github.com/FiloSottile/mkcert/releases">the pre-built binaries</a></p>
<h3 id="生成证书">生成证书</h3>
<p>需要首先在系统信任库中安装本地CA.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ mkcert -install ~
</span></span><span style="display:flex;"><span>Using the local CA at <span style="color:#e6db74">&#34;/home/angus/.local/share/mkcert&#34;</span> ✨
</span></span><span style="display:flex;"><span>The local CA is already installed in the system trust store! 👍
</span></span><span style="display:flex;"><span>The local CA is already installed in the Firefox and/or Chrome/Chromium trust store! 👍
</span></span></code></pre></div><p>完成后,您可以开始为您的域生成SSL证书。例如,我将生成一个对以下名称有效的新证书:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ mkcert myapp.net
</span></span><span style="display:flex;"><span>mkcert localhost ~/.ssl
</span></span><span style="display:flex;"><span>Using the local CA at <span style="color:#e6db74">&#34;/home/angus/.local/share/mkcert&#34;</span> ✨
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Created a new certificate valid <span style="color:#66d9ef">for</span> the following names 📜
</span></span><span style="display:flex;"><span> - <span style="color:#e6db74">&#34;myapp.net&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>The certificate is at <span style="color:#e6db74">&#34;./myapp.net.pem&#34;</span> and the key at <span style="color:#e6db74">&#34;./myapp.net-key.pem&#34;</span> ✅
</span></span></code></pre></div><h3 id="测试mkcert证书"><strong>测试mkcert证书</strong></h3>
<p>现在让我们使用一个简单的Nginx配置文件测试mkcert证书。</p>
<h3 id="创建一个简单的网页"><strong>创建一个简单的网页</strong></h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># cat /etc/nginx/conf.d/test.conf</span>
</span></span><span style="display:flex;"><span>server <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span> listen 80;
</span></span><span style="display:flex;"><span> server_name localhost;
</span></span><span style="display:flex;"><span> root /var/www/test;
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>server <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span> listen *:443 ssl http2;
</span></span><span style="display:flex;"><span> root /var/www/test;
</span></span><span style="display:flex;"><span> server_name localhost;
</span></span><span style="display:flex;"><span> ssl_certificate /home/angus/localhost.pem;
</span></span><span style="display:flex;"><span> ssl_certificate_key /home/angus/localhost-key.pem;
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span></code></pre></div><p>确保<code>/etc/hosts</code>文件包含已使用域的记录。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>127.0.0.1 myapp.net
</span></span></code></pre></div><p>打开浏览器并使用提供的域名,你应该得到一个绿色栏。</p>
</description>
</item>
<item>
<title>ArchLinux 触摸板手势调教</title>
<link>https://twor.me/posts/archlinux_gesture/</link>
<pubDate>Sun, 21 Mar 2021 23:58:53 +0800</pubDate>
<guid>https://twor.me/posts/archlinux_gesture/</guid>
<description><h2 id="wiki">WIKI</h2>
<p>比不上 Mac 的强大,简单的自定义,适合自己舒适就好。</p>
<ul>
<li>OS:Archlinux</li>
<li>WM:i3wm</li>
</ul>
<p>首先看一看wiki</p>
<blockquote>
<p>警告: <code>xf86-input-synaptics</code> 已经停止维护,请尽量使用 <code>libinput</code>。如果想要在 Xorg 上 安装 <code>libinput</code>,使用 <code>xf86-input-libinput</code> 包。此包允许 libinput 在 X 上作为驱动使用。此驱动会代替 <code>evdev</code> 和 <code>synaptics</code> 运行</p>
</blockquote>
<p>所以我们就需要安装 <code>xf86-input-libinput</code> 包</p>
<h2 id="安装触摸板驱动">安装触摸板驱动</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo pacman -S xf86-input-libinput
</span></span></code></pre></div><p>自定义配置文件应放在 <code>/etc/X11/xorg.conf.d/</code> 中,并且通常选择被广泛使用的命名模式 <code>30-touchpad.conf</code> 作为文件名</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo vim /etc/X11/xorg.conf.d/30-touchpad.conf
</span></span></code></pre></div><pre tabindex="0"><code class="language-conf" data-lang="conf">Section &#34;InputClass&#34;
Identifier &#34;touchpad&#34;
Driver &#34;libinput&#34;
MatchIsTouchpad &#34;on&#34;
Option &#34;Tapping&#34; &#34;on&#34;
Option &#34;TappingButtonMap&#34; &#34;lmr&#34;
EndSection
</code></pre><p>写入配置之后记得重新启动一下</p>
<h2 id="配置触摸板手势">配置触摸板手势</h2>
<h3 id="安装配置-libinput-gestures">安装配置 <code>libinput-gestures</code></h3>
<p>要使用 <code>libinput-gestures</code>, 请安装 <code>libinput-gestures</code>。 你能使用很多系统级别的手势操作,也能自定义配置文件。详情请看 <a href="https://github.com/bulletmark/libinput-gestures/blob/master/README.md">README</a> 。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo pacman -S libinput-gestures
</span></span></code></pre></div><p>libinput-gestures的文档中说了:必须是input组的成员才能具有读取触摸板设备的权限,所以需要添加用户到input</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo gpasswd -a $USER input
</span></span></code></pre></div><p>退出登录后生效(或者重启)</p>
<h3 id="安装配置-xdotool-wmctrl">安装配置 <code>xdotool wmctrl</code></h3>
<p>然后安装需要的包</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo pacman -S xdotool wmctrl
</span></span></code></pre></div><p>写入配置文件</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>vim .config/libinput-gestures.conf
</span></span></code></pre></div><pre tabindex="0"><code class="language-conf" data-lang="conf">gesture swipe left 4 xdotool key super+Ctrl+Left # 4指左划: 切换到左侧工作区
gesture swipe right 4 xdotool key super+Ctrl+Right # 4指右划: 切换到右侧工作区
gesture swipe up 4 xdotool key super+s # 4指上划: 堆叠窗口
gesture swipe down 4 xdotool key super+d # 4指下划: 还原窗口
gesture pinch in 4 xdotool key super+r # 4指捏: 调整窗口大小
gesture swipe left 3 xdotool key super+Shift+Left # 3指左划: 窗口移动到左边
gesture swipe right 3 xdotool key super+Shift+Right # 3指右划: 窗口移动到右边
gesture swipe up 3 xdotool key super+Shift+space # 3指下划: 浮动切换
gesture swipe down 3 xdotool key super+Shift+space # 3指上划: 浮动切换
gesture pinch in 3 xdotool key super+Shift+q # 3指捏: 关闭窗口
gesture pinch in 2 xdotool key ctrl+minus # 2指捏: 缩小
gesture pinch out 2 xdotool key ctrl+plus # 2指张: 放大%
</code></pre><p>这里可以根据自己的习惯来搭配,然后启动<code>ibinput-gestures</code>。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>libinput-gestures-setup autostart
</span></span><span style="display:flex;"><span>libinput-gestures-setup start
</span></span></code></pre></div><h2 id="演示">演示</h2>
<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
.aspect-ratio {
position: relative;
width: 100%;
height: 0;
padding-bottom: 75%;
}
.aspect-ratio iframe {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div class="aspect-ratio">
<iframe
src="https://player.bilibili.com/player.html?bvid=BV1Jy4y1h7DS&page=10"
scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"
sandbox="allow-top-navigation allow-same-origin allow-forms allow-scripts">
</iframe>
</div>
</body>
</html>
</description>
</item>
<item>
<title>我的Windows终端配置</title>
<link>https://twor.me/posts/windows_terminal/</link>
<pubDate>Tue, 18 Aug 2020 16:24:27 +0800</pubDate>
<guid>https://twor.me/posts/windows_terminal/</guid>
<description><h3 id="安装git"><strong>安装Git</strong></h3>
<p><a href="https://twor.me/%5BGit">下载</a></p>
<h3 id="配置主题"><strong>配置主题</strong></h3>
<p>打开 <code>Git Bash</code></p>
<pre tabindex="0"><code>$ git clone xxxx
$ cd xxxx
$ cp .minttyrc ~ &amp;&amp; cp git-prompt.sh /etc/profile.d
</code></pre><h3 id="安装-tmux"><strong>安装 Tmux</strong></h3>
<pre tabindex="0"><code>$ git clone https://github.com/hongwenjun/tmux_for_windows.git
$ cd tmux_for_windows/
$ unzip -x tmux_for_git-bash.zip -d /
</code></pre><h3 id="tmux-启用鼠标操作"><strong>tmux 启用鼠标操作</strong></h3>
<h3 id="tmuxconf-设定"><strong>.tmux.conf 设定</strong></h3>
<pre tabindex="0"><code># https://www.youtube.com/watch?v=xTplsyQaGFs
# tmux 启用鼠标操作
setw -g mouse
set-option -g history-limit 20000
set-option -g mouse on
bind -n WheelUpPane select-pane -t= \; copy-mode -e \; send-keys -M
bind -n WheelDownPane select-pane -t= \; send-keys -M
</code></pre><h3 id="安装-wget-和-tree-命令"><strong>安装 wget 和 tree 命令</strong></h3>
<pre tabindex="0"><code>$ cp tools/* /usr/bin
</code></pre><h2 id="其它"><strong>其它</strong></h2>
<h3 id="在-vscode-中配置git-bash"><strong>在 VSCode 中配置 <code>Git Bash</code></strong></h3>
<p>在 VSCode 中使用 <code>Git Bash</code> 只需要在 <code>Settings.json</code> 中添加如下两行即可,第一行中 <code>bash.exe</code> 的文件路径需要改成自己的,第二行是非必须配置,不配置无法使用 <code>alias</code>。</p>
<pre tabindex="0"><code>{
&#34;terminal.integrated.shell.windows&#34;: &#34;C:\\Program Files\\Git\\bin\\bash.exe&#34;,
&#34;terminal.integrated.shellArgs.windows&#34;: [&#34;--login&#34;, &#34;-i&#34;]
}
</code></pre><h3 id="解决-win10-快捷键不能秒启动问题"><strong>解决 win10 快捷键不能秒启动问题</strong></h3>
<p>为 <code>Git Bash</code> 设置了全局快捷键后,可能出现按下快捷键后延迟两秒左右终端才打开的现象,只需要在服务中禁用掉 <code>superFetch</code> 即可,此服务在比较新的 win10 上改名为了 <code>sysMain</code>,禁用服务后重启操作系统生效</p>
<h3 id="终端快捷键"><strong>终端快捷键</strong></h3>
<p>附 Git Bash 终端快捷键</p>
<p><a href="https://www.notion.so/b6fcd4975d2c4184a407471e760bc617">Untitled</a></p>
<h3 id="使用第三方工具"><strong>使用第三方工具</strong></h3>
<p><a href="https://eugeny.github.io/terminus/">Terminus</a></p>
<p>更直接,也很美观 <del>就是打开有点慢</del></p>
</description>
</item>
<item>
<title>Linux上优雅的控制手机(水群)</title>
<link>https://twor.me/posts/linux_android/</link>
<pubDate>Sat, 07 Mar 2020 13:58:53 +0800</pubDate>
<guid>https://twor.me/posts/linux_android/</guid>
<description><p>本文以ArchLinux为例</p>
<h3 id="手机控制-scrcpy">手机控制 <code>Scrcpy</code></h3>
<h4 id="安装-scrcpy">安装 <code>Scrcpy</code></h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ sudo pacman -S scrcpy
</span></span><span style="display:flex;"><span><span style="color:#75715e">#pacman会安装依赖包 android-tools</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#其他发行版如果没有请自行安装</span>
</span></span></code></pre></div><h4 id="查看设备id">查看设备ID</h4>
<p>首先用数据线连接上你的电脑和手机,在终端输入 <code>adb devices</code> 查看设备ID,其中 4dcb9ad5 为设备ID</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ adb devices
</span></span><span style="display:flex;"><span>* daemon not running; starting now at tcp:5037
</span></span><span style="display:flex;"><span>* daemon started successfully
</span></span><span style="display:flex;"><span>List of devices attached
</span></span><span style="display:flex;"><span>4dcb9ad5 no permissions; see <span style="color:#f92672">[</span>http://developer.android.com/tools/device.html<span style="color:#f92672">]</span>
</span></span></code></pre></div><h4 id="连接控制手机">连接控制手机</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ sudo -b scrcpy -s 4dcb9ad5 --turn-screen-off
</span></span><span style="display:flex;"><span><span style="color:#75715e">## 在后台并让手机保持熄屏运行</span>
</span></span></code></pre></div><ul>
<li><code>--turn-screen-off</code> 让手机保持熄屏状态</li>
</ul>
<p>如果不出意外,你的电脑应该可以直接显示和控制你的手机,但是这样手机就没法离电脑太远,如果你想要自由活动,往下看。</p>
<p>保持手机和电脑在同一局域网,使用 <code>adb tcpip 5555</code> 命令。如果出现错误请打开 <code>网络ADB调试</code> 和 <code>开启USB文件传输模式</code></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ adb tcpip <span style="color:#ae81ff">5555</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## 如果出现下面错误,请打开 网络ADB调试 和 开启USB文件传输模式</span>
</span></span><span style="display:flex;"><span>error: insufficient permissions <span style="color:#66d9ef">for</span> device
</span></span><span style="display:flex;"><span>See <span style="color:#f92672">[</span>http://developer.android.com/tools/device.html<span style="color:#f92672">]</span> <span style="color:#66d9ef">for</span> more information
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ adb tcpip <span style="color:#ae81ff">5555</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## 再试一次就成功了</span>
</span></span><span style="display:flex;"><span>restarting in TCP mode port: <span style="color:#ae81ff">5555</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ adb connect 192.168.1.3:5555
</span></span><span style="display:flex;"><span><span style="color:#75715e">## 成功连接手机 192.168.1.3 是你手机的ip</span>
</span></span><span style="display:flex;"><span>connected to 192.168.1.3:5555
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$ scrcpy -s 192.168.1.3:5555 --turn-screen-off
</span></span><span style="display:flex;"><span><span style="color:#75715e">## 使用scrcpy控制你的手机</span>
</span></span></code></pre></div><p>![aZWT41.png](<a href="https://s1.ax1x.com/2020/07/29/aZWT41.png">https://s1.ax1x.com/2020/07/29/aZWT41.png</a></p>
<p>数据线和WIFI的优势劣势</p>
<ul>
<li>数据线:可以小范围移动手机,但是传输画面比WIFI</li>
<li>WiFI:可以移动手机,自由活动。但是传输画面不是很好</li>
</ul>
<h4 id="使用情况">使用情况</h4>
<ul>
<li>可以双向复制/粘贴</li>
<li>可以使用电脑键盘打字聊天</li>
<li>基本满足日常水群,刷朋友圈</li>
<li>无法电脑截图分享(往下看)</li>
</ul>
<h3 id="文件同步">文件同步</h3>
<h4 id="安装-syncthing">安装 <code>syncthing</code></h4>
<ul>
<li>电脑</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ sudo pacman -S syncthing
</span></span></code></pre></div><ul>