This commit is contained in:
Teiva Harsanyi 2023-09-12 12:25:29 +02:00
parent 3a60ff2fca
commit f4ffe741c7
47 changed files with 3966 additions and 664 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View file

@ -1 +0,0 @@
TODO

60
docs/img/Go-Logo_Aqua.svg Normal file
View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 254.5 225" style="enable-background:new 0 0 254.5 225;" xml:space="preserve">
<style type="text/css">
.st0{fill:#2DBCAF;}
.st1{fill:#5DC9E1;}
.st2{fill:#FDDD00;}
.st3{fill:#CE3262;}
.st4{fill:#00ACD7;}
.st5{fill:#FFFFFF;}
</style>
<g>
<g>
<g>
<g>
<path class="st0" d="M40.2,101.1c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l35.7,0c0.4,0,0.5,0.3,0.3,0.6
l-1.7,2.6c-0.2,0.3-0.7,0.6-1,0.6L40.2,101.1z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st0" d="M25.1,110.3c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l45.6,0c0.4,0,0.6,0.3,0.5,0.6
l-0.8,2.4c-0.1,0.4-0.5,0.6-0.9,0.6L25.1,110.3z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st0" d="M49.3,119.5c-0.4,0-0.5-0.3-0.3-0.6l1.4-2.5c0.2-0.3,0.6-0.6,1-0.6l20,0c0.4,0,0.6,0.3,0.6,0.7l-0.2,2.4
c0,0.4-0.4,0.7-0.7,0.7L49.3,119.5z"/>
</g>
</g>
</g>
<g>
<g id="CXHf1q_1_">
<g>
<g>
<path class="st0" d="M153.1,99.3c-6.3,1.6-10.6,2.8-16.8,4.4c-1.5,0.4-1.6,0.5-2.9-1c-1.5-1.7-2.6-2.8-4.7-3.8
c-6.3-3.1-12.4-2.2-18.1,1.5c-6.8,4.4-10.3,10.9-10.2,19c0.1,8,5.6,14.6,13.5,15.7c6.8,0.9,12.5-1.5,17-6.6
c0.9-1.1,1.7-2.3,2.7-3.7c-3.6,0-8.1,0-19.3,0c-2.1,0-2.6-1.3-1.9-3c1.3-3.1,3.7-8.3,5.1-10.9c0.3-0.6,1-1.6,2.5-1.6
c5.1,0,23.9,0,36.4,0c-0.2,2.7-0.2,5.4-0.6,8.1c-1.1,7.2-3.8,13.8-8.2,19.6c-7.2,9.5-16.6,15.4-28.5,17
c-9.8,1.3-18.9-0.6-26.9-6.6c-7.4-5.6-11.6-13-12.7-22.2c-1.3-10.9,1.9-20.7,8.5-29.3c7.1-9.3,16.5-15.2,28-17.3
c9.4-1.7,18.4-0.6,26.5,4.9c5.3,3.5,9.1,8.3,11.6,14.1C154.7,98.5,154.3,99,153.1,99.3z"/>
</g>
<g>
<path class="st0" d="M186.2,154.6c-9.1-0.2-17.4-2.8-24.4-8.8c-5.9-5.1-9.6-11.6-10.8-19.3c-1.8-11.3,1.3-21.3,8.1-30.2
c7.3-9.6,16.1-14.6,28-16.7c10.2-1.8,19.8-0.8,28.5,5.1c7.9,5.4,12.8,12.7,14.1,22.3c1.7,13.5-2.2,24.5-11.5,33.9
c-6.6,6.7-14.7,10.9-24,12.8C191.5,154.2,188.8,154.3,186.2,154.6z M210,114.2c-0.1-1.3-0.1-2.3-0.3-3.3
c-1.8-9.9-10.9-15.5-20.4-13.3c-9.3,2.1-15.3,8-17.5,17.4c-1.8,7.8,2,15.7,9.2,18.9c5.5,2.4,11,2.1,16.3-0.6
C205.2,129.2,209.5,122.8,210,114.2z"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

60
docs/img/Go-Logo_Blue.svg Normal file
View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 254.5 225" style="enable-background:new 0 0 254.5 225;" xml:space="preserve">
<style type="text/css">
.st0{fill:#2DBCAF;}
.st1{fill:#5DC9E1;}
.st2{fill:#FDDD00;}
.st3{fill:#CE3262;}
.st4{fill:#00ACD7;}
.st5{fill:#FFFFFF;}
</style>
<g>
<g>
<g>
<g>
<path class="st4" d="M40.2,101.1c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l35.7,0c0.4,0,0.5,0.3,0.3,0.6
l-1.7,2.6c-0.2,0.3-0.7,0.6-1,0.6L40.2,101.1z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st4" d="M25.1,110.3c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l45.6,0c0.4,0,0.6,0.3,0.5,0.6
l-0.8,2.4c-0.1,0.4-0.5,0.6-0.9,0.6L25.1,110.3z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st4" d="M49.3,119.5c-0.4,0-0.5-0.3-0.3-0.6l1.4-2.5c0.2-0.3,0.6-0.6,1-0.6l20,0c0.4,0,0.6,0.3,0.6,0.7l-0.2,2.4
c0,0.4-0.4,0.7-0.7,0.7L49.3,119.5z"/>
</g>
</g>
</g>
<g>
<g id="CXHf1q_3_">
<g>
<g>
<path class="st4" d="M153.1,99.3c-6.3,1.6-10.6,2.8-16.8,4.4c-1.5,0.4-1.6,0.5-2.9-1c-1.5-1.7-2.6-2.8-4.7-3.8
c-6.3-3.1-12.4-2.2-18.1,1.5c-6.8,4.4-10.3,10.9-10.2,19c0.1,8,5.6,14.6,13.5,15.7c6.8,0.9,12.5-1.5,17-6.6
c0.9-1.1,1.7-2.3,2.7-3.7c-3.6,0-8.1,0-19.3,0c-2.1,0-2.6-1.3-1.9-3c1.3-3.1,3.7-8.3,5.1-10.9c0.3-0.6,1-1.6,2.5-1.6
c5.1,0,23.9,0,36.4,0c-0.2,2.7-0.2,5.4-0.6,8.1c-1.1,7.2-3.8,13.8-8.2,19.6c-7.2,9.5-16.6,15.4-28.5,17
c-9.8,1.3-18.9-0.6-26.9-6.6c-7.4-5.6-11.6-13-12.7-22.2c-1.3-10.9,1.9-20.7,8.5-29.3c7.1-9.3,16.5-15.2,28-17.3
c9.4-1.7,18.4-0.6,26.5,4.9c5.3,3.5,9.1,8.3,11.6,14.1C154.7,98.5,154.3,99,153.1,99.3z"/>
</g>
<g>
<path class="st4" d="M186.2,154.6c-9.1-0.2-17.4-2.8-24.4-8.8c-5.9-5.1-9.6-11.6-10.8-19.3c-1.8-11.3,1.3-21.3,8.1-30.2
c7.3-9.6,16.1-14.6,28-16.7c10.2-1.8,19.8-0.8,28.5,5.1c7.9,5.4,12.8,12.7,14.1,22.3c1.7,13.5-2.2,24.5-11.5,33.9
c-6.6,6.7-14.7,10.9-24,12.8C191.5,154.2,188.8,154.3,186.2,154.6z M210,114.2c-0.1-1.3-0.1-2.3-0.3-3.3
c-1.8-9.9-10.9-15.5-20.4-13.3c-9.3,2.1-15.3,8-17.5,17.4c-1.8,7.8,2,15.7,9.2,18.9c5.5,2.4,11,2.1,16.3-0.6
C205.2,129.2,209.5,122.8,210,114.2z"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 254.5 225" style="enable-background:new 0 0 254.5 225;" xml:space="preserve">
<style type="text/css">
.st0{fill:#2DBCAF;}
.st1{fill:#5DC9E1;}
.st2{fill:#FDDD00;}
.st3{fill:#CE3262;}
.st4{fill:#00ACD7;}
.st5{fill:#FFFFFF;}
</style>
<g>
<g>
<g>
<g>
<path class="st1" d="M40.2,101.1c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l35.7,0c0.4,0,0.5,0.3,0.3,0.6
l-1.7,2.6c-0.2,0.3-0.7,0.6-1,0.6L40.2,101.1z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st1" d="M25.1,110.3c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l45.6,0c0.4,0,0.6,0.3,0.5,0.6
l-0.8,2.4c-0.1,0.4-0.5,0.6-0.9,0.6L25.1,110.3z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st1" d="M49.3,119.5c-0.4,0-0.5-0.3-0.3-0.6l1.4-2.5c0.2-0.3,0.6-0.6,1-0.6l20,0c0.4,0,0.6,0.3,0.6,0.7l-0.2,2.4
c0,0.4-0.4,0.7-0.7,0.7L49.3,119.5z"/>
</g>
</g>
</g>
<g>
<g id="CXHf1q_7_">
<g>
<g>
<path class="st1" d="M153.1,99.3c-6.3,1.6-10.6,2.8-16.8,4.4c-1.5,0.4-1.6,0.5-2.9-1c-1.5-1.7-2.6-2.8-4.7-3.8
c-6.3-3.1-12.4-2.2-18.1,1.5c-6.8,4.4-10.3,10.9-10.2,19c0.1,8,5.6,14.6,13.5,15.7c6.8,0.9,12.5-1.5,17-6.6
c0.9-1.1,1.7-2.3,2.7-3.7c-3.6,0-8.1,0-19.3,0c-2.1,0-2.6-1.3-1.9-3c1.3-3.1,3.7-8.3,5.1-10.9c0.3-0.6,1-1.6,2.5-1.6
c5.1,0,23.9,0,36.4,0c-0.2,2.7-0.2,5.4-0.6,8.1c-1.1,7.2-3.8,13.8-8.2,19.6c-7.2,9.5-16.6,15.4-28.5,17
c-9.8,1.3-18.9-0.6-26.9-6.6c-7.4-5.6-11.6-13-12.7-22.2c-1.3-10.9,1.9-20.7,8.5-29.3c7.1-9.3,16.5-15.2,28-17.3
c9.4-1.7,18.4-0.6,26.5,4.9c5.3,3.5,9.1,8.3,11.6,14.1C154.7,98.5,154.3,99,153.1,99.3z"/>
</g>
<g>
<path class="st1" d="M186.2,154.6c-9.1-0.2-17.4-2.8-24.4-8.8c-5.9-5.1-9.6-11.6-10.8-19.3c-1.8-11.3,1.3-21.3,8.1-30.2
c7.3-9.6,16.1-14.6,28-16.7c10.2-1.8,19.8-0.8,28.5,5.1c7.9,5.4,12.8,12.7,14.1,22.3c1.7,13.5-2.2,24.5-11.5,33.9
c-6.6,6.7-14.7,10.9-24,12.8C191.5,154.2,188.8,154.3,186.2,154.6z M210,114.2c-0.1-1.3-0.1-2.3-0.3-3.3
c-1.8-9.9-10.9-15.5-20.4-13.3c-9.3,2.1-15.3,8-17.5,17.4c-1.8,7.8,2,15.7,9.2,18.9c5.5,2.4,11,2.1,16.3-0.6
C205.2,129.2,209.5,122.8,210,114.2z"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 254.5 225" style="enable-background:new 0 0 254.5 225;" xml:space="preserve">
<style type="text/css">
.st0{fill:#2DBCAF;}
.st1{fill:#5DC9E1;}
.st2{fill:#FDDD00;}
.st3{fill:#CE3262;}
.st4{fill:#00ACD7;}
.st5{fill:#FFFFFF;}
</style>
<g>
<g>
<g>
<g>
<path class="st5" d="M40.2,101.1c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l35.7,0c0.4,0,0.5,0.3,0.3,0.6
l-1.7,2.6c-0.2,0.3-0.7,0.6-1,0.6L40.2,101.1z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st5" d="M25.1,110.3c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l45.6,0c0.4,0,0.6,0.3,0.5,0.6
l-0.8,2.4c-0.1,0.4-0.5,0.6-0.9,0.6L25.1,110.3z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st5" d="M49.3,119.5c-0.4,0-0.5-0.3-0.3-0.6l1.4-2.5c0.2-0.3,0.6-0.6,1-0.6l20,0c0.4,0,0.6,0.3,0.6,0.7l-0.2,2.4
c0,0.4-0.4,0.7-0.7,0.7L49.3,119.5z"/>
</g>
</g>
</g>
<g>
<g id="CXHf1q_2_">
<g>
<g>
<path class="st5" d="M153.1,99.3c-6.3,1.6-10.6,2.8-16.8,4.4c-1.5,0.4-1.6,0.5-2.9-1c-1.5-1.7-2.6-2.8-4.7-3.8
c-6.3-3.1-12.4-2.2-18.1,1.5c-6.8,4.4-10.3,10.9-10.2,19c0.1,8,5.6,14.6,13.5,15.7c6.8,0.9,12.5-1.5,17-6.6
c0.9-1.1,1.7-2.3,2.7-3.7c-3.6,0-8.1,0-19.3,0c-2.1,0-2.6-1.3-1.9-3c1.3-3.1,3.7-8.3,5.1-10.9c0.3-0.6,1-1.6,2.5-1.6
c5.1,0,23.9,0,36.4,0c-0.2,2.7-0.2,5.4-0.6,8.1c-1.1,7.2-3.8,13.8-8.2,19.6c-7.2,9.5-16.6,15.4-28.5,17
c-9.8,1.3-18.9-0.6-26.9-6.6c-7.4-5.6-11.6-13-12.7-22.2c-1.3-10.9,1.9-20.7,8.5-29.3c7.1-9.3,16.5-15.2,28-17.3
c9.4-1.7,18.4-0.6,26.5,4.9c5.3,3.5,9.1,8.3,11.6,14.1C154.7,98.5,154.3,99,153.1,99.3z"/>
</g>
<g>
<path class="st5" d="M186.2,154.6c-9.1-0.2-17.4-2.8-24.4-8.8c-5.9-5.1-9.6-11.6-10.8-19.3c-1.8-11.3,1.3-21.3,8.1-30.2
c7.3-9.6,16.1-14.6,28-16.7c10.2-1.8,19.8-0.8,28.5,5.1c7.9,5.4,12.8,12.7,14.1,22.3c1.7,13.5-2.2,24.5-11.5,33.9
c-6.6,6.7-14.7,10.9-24,12.8C191.5,154.2,188.8,154.3,186.2,154.6z M210,114.2c-0.1-1.3-0.1-2.3-0.3-3.3
c-1.8-9.9-10.9-15.5-20.4-13.3c-9.3,2.1-15.3,8-17.5,17.4c-1.8,7.8,2,15.7,9.2,18.9c5.5,2.4,11,2.1,16.3-0.6
C205.2,129.2,209.5,122.8,210,114.2z"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 254.5 225" style="enable-background:new 0 0 254.5 225;" xml:space="preserve">
<style type="text/css">
.st0{fill:#2DBCAF;}
.st1{fill:#5DC9E1;}
.st2{fill:#FDDD00;}
.st3{fill:#CE3262;}
.st4{fill:#00ACD7;}
.st5{fill:#FFFFFF;}
</style>
<g>
<g>
<g>
<g>
<path class="st2" d="M40.2,101.1c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l35.7,0c0.4,0,0.5,0.3,0.3,0.6
l-1.7,2.6c-0.2,0.3-0.7,0.6-1,0.6L40.2,101.1z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st2" d="M25.1,110.3c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l45.6,0c0.4,0,0.6,0.3,0.5,0.6
l-0.8,2.4c-0.1,0.4-0.5,0.6-0.9,0.6L25.1,110.3z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st2" d="M49.3,119.5c-0.4,0-0.5-0.3-0.3-0.6l1.4-2.5c0.2-0.3,0.6-0.6,1-0.6l20,0c0.4,0,0.6,0.3,0.6,0.7l-0.2,2.4
c0,0.4-0.4,0.7-0.7,0.7L49.3,119.5z"/>
</g>
</g>
</g>
<g>
<g id="CXHf1q_6_">
<g>
<g>
<path class="st2" d="M153.1,99.3c-6.3,1.6-10.6,2.8-16.8,4.4c-1.5,0.4-1.6,0.5-2.9-1c-1.5-1.7-2.6-2.8-4.7-3.8
c-6.3-3.1-12.4-2.2-18.1,1.5c-6.8,4.4-10.3,10.9-10.2,19c0.1,8,5.6,14.6,13.5,15.7c6.8,0.9,12.5-1.5,17-6.6
c0.9-1.1,1.7-2.3,2.7-3.7c-3.6,0-8.1,0-19.3,0c-2.1,0-2.6-1.3-1.9-3c1.3-3.1,3.7-8.3,5.1-10.9c0.3-0.6,1-1.6,2.5-1.6
c5.1,0,23.9,0,36.4,0c-0.2,2.7-0.2,5.4-0.6,8.1c-1.1,7.2-3.8,13.8-8.2,19.6c-7.2,9.5-16.6,15.4-28.5,17
c-9.8,1.3-18.9-0.6-26.9-6.6c-7.4-5.6-11.6-13-12.7-22.2c-1.3-10.9,1.9-20.7,8.5-29.3c7.1-9.3,16.5-15.2,28-17.3
c9.4-1.7,18.4-0.6,26.5,4.9c5.3,3.5,9.1,8.3,11.6,14.1C154.7,98.5,154.3,99,153.1,99.3z"/>
</g>
<g>
<path class="st2" d="M186.2,154.6c-9.1-0.2-17.4-2.8-24.4-8.8c-5.9-5.1-9.6-11.6-10.8-19.3c-1.8-11.3,1.3-21.3,8.1-30.2
c7.3-9.6,16.1-14.6,28-16.7c10.2-1.8,19.8-0.8,28.5,5.1c7.9,5.4,12.8,12.7,14.1,22.3c1.7,13.5-2.2,24.5-11.5,33.9
c-6.6,6.7-14.7,10.9-24,12.8C191.5,154.2,188.8,154.3,186.2,154.6z M210,114.2c-0.1-1.3-0.1-2.3-0.3-3.3
c-1.8-9.9-10.9-15.5-20.4-13.3c-9.3,2.1-15.3,8-17.5,17.4c-1.8,7.8,2,15.7,9.2,18.9c5.5,2.4,11,2.1,16.3-0.6
C205.2,129.2,209.5,122.8,210,114.2z"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

Before

Width:  |  Height:  |  Size: 402 KiB

After

Width:  |  Height:  |  Size: 402 KiB

View file

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 76 KiB

View file

Before

Width:  |  Height:  |  Size: 3.5 MiB

After

Width:  |  Height:  |  Size: 3.5 MiB

View file

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

View file

@ -1,12 +1,8 @@
---
title: 100 Go Mistakes and How to Avoid Them
---
# 📖 Book Presentation
Source code and community space of _100 Go Mistakes and How to Avoid Them_, published by Manning in 2022.
![](cover.png)
![](img/cover.png)
## Book Description

View file

@ -1,20 +1,3 @@
---
title: Go Jobs
---
# ❤️ Go Jobs
Is your company hiring? [Sponsor](https://github.com/sponsors/teivah/sponsorships?sponsor=teivah&tier_id=316526&preview=true) this repository and let Go developers know your opportunities in this section (traffic: +400 unique visitor per week).
For example:
# [Company] Remote (USA) - $96,000 to $120,000 a year
## Job Description
...
## Qualifications
...
Is your company hiring? [Sponsor](https://github.com/sponsors/teivah/sponsorships?sponsor=teivah&tier_id=316526&preview=true) this repository and let a significant audience of Go developers know about your opportunities in this section (book sales: +8k, website traffic: +2000 views and +400 unique visitors per week).

View file

@ -1,7 +1,3 @@
---
title: Common Go Mistakes
---
# 💡 Go Mistakes
This section contains a summary of the 100 mistakes in the book. Meanwhile, it's also a section open to the community. If you believe that a mistake should be added, please create a [community mistake issue](https://github.com/teivah/100-go-mistakes/issues/new?assignees=&labels=community+mistake&template=community_mistake.md&title=).
@ -12,7 +8,7 @@ This section contains a summary of the 100 mistakes in the book. Meanwhile, it's
<!-- TODO Include chapter-1.md -->
![](inside-cover.png)
![](img/inside-cover.png)
## Code and Project Organization
@ -32,43 +28,44 @@ In general, the more nested levels a function requires, the more complex it is t
* When an `if` block returns, we should omit the `else` block in all cases. For example, we shouldnt write:
```go
if foo() {
// ...
return true
} else {
// ...
}
```
```go
if foo() {
// ...
return true
} else {
// ...
}
```
Instead, we omit the `else` block like this:
```go
if foo() {
// ...
return true
}
// ...
```
```go
if foo() {
// ...
return true
}
// ...
```
* We can also follow this logic with a non-happy path:
```go
if s != "" {
// ...
} else {
return errors.New("empty string")
}
```
```go
if s != "" {
// ...
} else {
return errors.New("empty string")
}
```
Here, an empty `s` represents the non-happy path. Hence, we should flip the
condition like so:
```go
if s == "" {
return errors.New("empty string")
}
// ...
```
```go
if s == "" {
return errors.New("empty string")
}
// ...
```
Writing readable code is an important challenge for every developer. Striving to reduce the number of nested blocks, aligning the happy path on the left, and returning as early as possible are concrete means to improve our codes readability.
@ -193,7 +190,7 @@ Although there are different implementations with minor variations, the main ide
* An unexported struct holds the configuration: options.
* Each option is a function that returns the same type: `type Option func(options *options)` error. For example, `WithPort` accepts an `int` argument that represents the port and returns an `Option` type that represents how to update the `options` struct.
![](options.png)
![](img/options.png)
```go
type options struct {
@ -691,7 +688,7 @@ Lets start with the last observation. We already mentioned that len returns t
Meanwhile, in the previous example, we have to understand that we don't iterate over each rune; instead, we iterate over each starting index of a rune:
![](rune.png)
![](img/rune.png)
Printing `s[i]` doesnt print the ith rune; it prints the UTF-8 representation of the byte at index `i`. Hence, we printed "hÃllo" instead of "hêllo".
@ -738,7 +735,7 @@ fmt.Println(strings.TrimRight("123oxo", "xo"))
The example prints 123:
![](trim.png)
![](img/trim.png)
Conversely, `strings.TrimLeft` removes all the leading runes contained in a set.

545
docs/zh/index.md Normal file
View file

@ -0,0 +1,545 @@
# 100个Go常见错误及如何避免
## 代码及工程组织
### 意外的变量隐藏 (#1)
Avoiding shadowed variables can help prevent mistakes like referencing the wrong variable or confusing readers.
避免变量隐藏(外部作用域变量被内部作用域同名变量隐藏),有助于避免变量引用错误,有助于他人阅读理解。
### 不必要的代码嵌套 (#2)
避免不必要的、过多的嵌套层次,并且让正常代码路径尽量左对齐(而不是放在分支路径中),有助于构建可读性更好的代码。
### 误用init函数 (#3)
初始化变量时,请记住 init 函数具有有限的错误处理能力,并且会使状态处理和测试变得更加复杂。在大多数情况下,初始化应该作为特定函数来处理。
### 滥用getters/setters (#4)
在Go语言中强制使用getter和setter方法并不符合Go惯例。在实践中应该找到效率和盲目遵循某些惯用法之间的平衡点。
### 接口污染 (#5)
抽象应该被发现,而不是被创造。为了避免不必要的复杂性,需要时才创建接口,而不是预见到需要它,或者至少可以证明这种抽象是有价值的。
### 将接口定义在实现方一侧 (#6)
将接口保留在引用方一侧(而不是实现方一侧)可以避免不必要的抽象。
### 将接口作为返回值 (#7)
为了避免在灵活性方面受到限制,大多数情况下函数不应该返回接口,而应该返回具体的实现。相反,函数应该尽可能地使用接口作为参数。
### `any` 没传递任何信息 (#8)
只有在需要接受或返回任意类型时,才使用 `any`,例如 `json.Marshal`。其他情况下,因为 `any` 不提供有意义的信息,可能会导致编译时问题,如允许调用者调用方法处理任意类型数据。
### [困惑何时该用范型](https://teivah.medium.com/when-to-use-generics-in-go-36d49c1aeda) (#9)
使用泛型,可以通过类型参数分离具体的数据类型和行为,避免写很多重复度很高的代码。然而,不要过早地使用泛型、类型参数,只有在你看到真正需要时才使用。否则,它们会引入不必要的抽象和复杂性。
### 未意识到类型嵌套的可能问题 (#10)
使用类型嵌套也可以避免写一些重复代码,然而,在使用时需要确保不会导致不合理的可见性问题,比如有些字段应该对外隐藏不应该被暴漏。
### 不使用function option模式 (#11)
为了设计并提供更友好的API可选参数为了更好地处理选项应该使用function option模式。
### 工程组织不合理 (工程结构和包的组织) (#12)
遵循像 project-layout 的建议来组织Go工程是一个不错的方法特别是你正在寻找一些类似的经验、惯例来组织一个新的Go工程的时候。
### 创建工具包 (#13)
命名是软件设计开发中非常重要的一个部分,创建一些名如 `common`、`util`、`shared` 之类的包名并不会给读者带来太大价值,应该将这些包名重构为更清晰、更聚焦的包名。
### 忽略了包名冲突 (#14)
To avoid naming collisions between variables and packages, leading to confusion or perhaps even bugs, use unique names for each one. If this isnt feasible, use an import alias to change the qualifier to differentiate the package name from the variable name, or think of a better name.
为了避免变量名和包名之间的冲突,导致混淆或甚至错误,应为每个变量和包使用唯一的名称。如果这不可行,可以考虑使用导入别名 `import importAlias 'importPath'`,以区分包名和变量名,或者考虑一个更好的变量名。
### 代码缺少文档 (#15)
为了让使用方、维护人员能更清晰地了解你的代码的意图导出的元素函数、类型、字段需要添加godoc注释。
### 不使用linters检查 (#16)
为了改善代码质量、整体代码的一致性应该使用linters、formatters。
## 数据类型
### 八进制字面量引发的困惑 (#17)
在阅读现有代码时,请记住以 0 开头的整数字面量是八进制数。此外,为了提高可读性,可以通过在前面加上 0o 来显式地表示八进制整数。
### 未注意可能的整数溢出 (#18)
在 Go 中整数上溢出和下溢是静默处理的,所以你可以实现自己的函数来捕获它们。
### 没有透彻理解浮点数 (#19)
比较浮点数时通过比较二者的delta值是否介于一定的范围内能让你写出可移植性更好的代码。
在进行加法或减法时,将具有相似数量级的操作分成同一组以提高精度 (过早指数对齐丢失精度)。此外,在进行加法和减法之前,应先进行乘法和除法 (加减法误差会被乘除放大)。
### [不理解slice的长度和容量](https://teivah.medium.com/slice-length-vs-capacity-in-go-af71a754b7d8) (#20)
理解slice的长度和容量的区别是一个Go开发者的核心知识点之一。slice的长度指的是slice已经存储的元素的数量而容量指的是slice当前底层开辟的数组最多能容纳的元素的数量。
### 不高效的slice初始化 (#21)
当创建一个slice时如果其长度可以预先确定那么可以在定义时指定它的长度和容量。这可以改善后期append时一次或者多次的内存分配操作从而改善性能。对于map的初始化也是这样的。
### 困惑于nil和空slice (#22)
为了避免常见的对nil和empty slice处理行为的混淆例如在使用 encoding/json 或 reflect 包时,你需要理解 nil 和 empty slice的区别。两者都是长度为零、容量为零的切片但是 nil 切片不需要分配内存。
### 没有适当检查slice是否为空 (#23)
检查一个slice的是否包含任何元素可以检查其长度不管slice是nil还是empty检查长度都是有效的。这个检查方法也适用于map。
为了设计更明确的APIAPI不应区分nil和空切片。
### 没有正确拷贝slice (#24)
使用 `copy` 拷贝一个slice元素到另一个slice时需要记得实际拷贝的元素数量是二者slice长度中的较小值。
### slice append带来的预期之外的副作用 (#25)
如果两个不同的函数操作的slice复用了相同的底层数组它们对slice执行append操作时可能会产生冲突。使用copy来完整复制一个slice或者使用完整的slice表达式[low:high:max]限制最大容量有助于避免产生冲突。当想对一个大slice进行shrink操作时两种方式中只有copy才可以避免内存泄漏。
### slice和内存泄漏 (#26)
对于slice元素为指针或者slice元素为struct但是该struct含有指针字段当通过slice[low:high]操作取subslice时对于那些不可访问的元素可以显示设置为nil来避免内存泄露。
### 不高效的map初始化 (#27)
见 [#21](#inefficient-slice-initialization-21).
### [map和内存泄漏](https://teivah.medium.com/maps-and-memory-leaks-in-go-a85ebe6e7e69) (#28)
一个map的buckets占用的内存只会增长不会缩减。因此如果它导致了一些内存占用的问题你需要尝试不同的选项来解决比如重新创建一个map代替原来的原来的map会被GC掉或者map[keyType]valueType中的valueType使用指针代替长度固定的数组或者sliceHeader来缓解过多的内存占用。
### 不正确的值比较 (#29)
Go中比较两个类型值时如果是可比较类型那么可以使用 `==` 或者 `!=` 运算符进行比较比如booleans、numerals、strings、pointers、channels以及字段全部是可比较类型的structs。其他情况下你可以使用 `reflect.DeepEqual` 来比较,用反射的话会牺牲一点性能,也可以使用自定义的实现和其他库来完成。
## 控制结构
### 忽略了 `range` 循环变量是一个拷贝 (#30)
`range` 循环中的循环变量是遍历容器中元素值的一个拷贝。因此如果元素值是一个struct并且想在 `range` 中修改它可以通过索引值来访问并修改它或者使用经典的for循环+索引值的写法(除非遍历的元素是一个指针)。
### 忽略了 `range` 循环中迭代目标值的计算方式 (channels 和 arrays) (#31)
传递给 `range` 操作的迭代目标对应的表达式的值只会在循环执行前被计算一次理解这个有助于避免犯一些常见的错误例如不高效的channel赋值操作、slice迭代操作。
### 忽略了 `range` 循环中指针元素的影响 `range` loops (#32)
这里其实强调的是 `range` 迭代过程中迭代变量实际上是一个拷贝假设给另外一个容器元素指针类型赋值且需要对迭代变量取地址转换成指针再赋值的话这里潜藏着一个错误就是for循环迭代变量是 per-variable-per-loop 而不是 per-variable-per-iteration。如果是通过局部变量用迭代变量来初始化或者使用索引值来直接引用迭代的元素将有助于避免拷贝指针(迭代变量的地址)之类的bug。
### map迭代过程中的错误假设遍历顺序 和 迭代过程中插入)(#33)
使用map时为了能得到确定一致的结果应该记住Go中的map数据结构
* 不会按照key对data进行排序遍历时不是按key有序的
* 遍历时的顺序,也不是按照插入时的顺序;
* 没有一个确定性的遍历顺序,每次遍历顺序是不同的;
* 不能保证迭代过程中新插入的元素,在当前迭代中能够被遍历到;
### 忽略了 `break` 语句是如何工作的 (#34)
配合label使用 `break``continue`,能够跳过一个特定的语句,在某些循环中存在 `switch`和`select`语句的场景中就比较有帮助。
### 在循环中使用 `defer` (#35)
在循环中使用defer不能在每轮迭代结束时执行defer语句但是将循环逻辑提取到函数内部会在每次迭代结束时执行 defer 语句。
## 字符串
### 没有理解rune (#36)
理解rune类型对应的是一个unicode码点每一个unicode码点其实是一个多字节的序列不是一个byte。这应该是Go开发者的核心知识点之一理解了这个有助于更准确地处理字符串。
### 不正确的字符串遍历 (#37)
使用 `range` 操作符对一个string进行遍历实际上是对string对应的 `[]rune` 进行遍历迭代变量中的索引值表示的当前rune对应的 `[]byte` 在整个 `[]byte(string)` 中的起始索引。如果要访问string中的某一个rune比如第三个首先要将字符串转换为 `[]rune` 然后再按索引值访问。
### 误用trim函数 (#38)
`strings.TrimRight`/`strings.TrimLeft` 移除在字符串尾部或者开头出现的一些runes函数会指定一个rune集合出现在集合中的rune将被从字符串移除。而 `strings.TrimSuffix`/`strings.TrimPrefix` 是移除字符串的一个后缀/前缀。
### 不经优化的字符串拼接操作 (#39)
对一个字符串列表进行遍历拼接操作,应该通过 `strings.Builder` 来完成以避免每次迭代拼接时都分配一个新的string对象出来。
### 无用的字符串转换 (#40)
`bytes` 包提供了一些和 `strings` 包相似的操作,可以帮助避免 []byte/string 之间的转换。
### 子字符串和内存泄漏 (#41)
使用一个子字符串的拷贝有助于避免内存泄漏因为对一个字符串的s[low:high]操作返回的子字符串其使用了和原字符串s相同的底层数组。
## 函数和方法
### 不知道使用哪种接收器类型 (#42)
对于接收器类型是采用value类型还是pointer类型应该取决于下面这几种因素比如方法内是否会对它进行修改它是否包含了一个不能被拷贝的字段以及它表示的对象有多大。如果有疑问接收器可以考虑使用pointer类型。
### 从不使用命名的返回值 (#43)
使用命名的返回值,是一种有效改善函数、方法可读性的方法,特别是返回值列表中有多个类型相同的参数。另外,因为返回值列表中的参数是经过零值初始化过的,某些场景下也会简化函数、方法的实现。但是需要注意它的一些潜在副作用。
### 使用命名的返回值时预期外的副作用 (#44)
见 [#43](#从不使用命名的返回值-43).
使用命名的返回值,因为它已经被初始化了零值,需要注意在某些情况下异常返回时是否需要给它赋予一个不同的值,比如返回值列表定义了一个有名参数 `err error`,需要注意 `return err` 时是否正确地对 `err` 进行了赋值。
### 返回一个nil接收器 (#45)
当返回一个interface参数时需要小心不要返回一个nil指针而是应该显示返回一个nil值。否则可能会发生一些预期外的问题因为调用方会收到一个非nil的值。
### 使用文件名作为函数入参 (#46)
设计函数时使用 `io.Reader` 类型作为入参,而不是文件名,将有助于改善函数的可复用性、易测试性。
### 忽略 `defer` 语句中参数、接收器值的计算方式 (参数值计算, 指针, 和 value类型接收器) (#47)
为了避免 `defer` 语句执行时就立即计算对defer要执行的函数的参数进行计算可以考虑将要执行的函数放到闭包里面然后通过指针传递参数给闭包内函数或者通过闭包捕获外部变量来解决这个问题。
## 错误管理
### Panicking (#48)
使用 `panic` 是Go中一种处理错误的方式但是只能在遇到不可恢复的错误时使用例如通知开发人员一个强依赖的模块加载失败了。
### 未考虑何时才应该包装error (#49)
Wrapping包装错误允许您标记错误、提供额外的上下文信息。然而包装错误会创建潜在的耦合因为它使得原来的错误对调用者可见。如果您想要防止这种情况请不要使用包装错误的方式。
### 不正确的错误类型比较 (#50)
如果你使用 Go 1.13 引入的特性 `fmt.Errorf` + `%w` 来包装一个错误,当进行错误比较时,如果想判断该包装后的错误是不是指定的错误类型,就需要使用 `errors.As`如果想判断是不是指定的error对象就需要用 `errors.Is`
### 不正确的错误对象值比较 (#51)
见 [#50](#不正确的错误类型比较-50).
为了表达一个预期内的错误,请使用错误值的方式,并通过 `==` 或者 `errors.Is` 来比较。而对于意外错误,则应使用特定的错误类型(可以通过 `errors.As` 来比较)。
### 处理同一个错误两次 (#52)
大多数情况下,错误仅需要处理一次。打印错误日志也是一种错误处理。因此,当函数内发生错误时,应该在打印日志和返回错误中选择其中一种。包装错误也可以提供问题发生的额外上下文信息,也包括了原来的错误(可考虑交给调用方负责打日志)。
### 不处理错误 (#53)
不管是在函数调用时,还是在一个 `defer` 函数执行时,如果想要忽略一个错误,应该显示地通过 `_` 来忽略(可注明忽略的原因)。否则,将来的读者就会感觉到困惑,忽略这个错误是有意为之还是无意中漏掉了。
### 不处理 `defer` 中的错误 (#54)
大多数情况下,你不应该忽略 `defer` 函数执行时返回的错误,或者显示处理它,或者将它传递给调用方处理,可以根据情景进行选择。如果你确定要忽略这个错误,请显示使用 `_` 来忽略。
## 并发编程: 基础
### 混淆并发和并行 (#55)
理解并发concurrency、并行parallelism之间的本质区别是Go开发人员必须要掌握的。并发是关于结构设计上的并行是关于具体执行上的。
### [认为并发总是更快](https://teivah.medium.com/concurrency-isnt-always-faster-in-go-de325168907c) (#56)
要成为一名熟练的开发人员您必须意识到并非所有场景下都是并发的方案更快。对于任务中的最小工作负载部分对它们进行并行化处理并不一定就有明显收益或者比串行化方案更快。对串行化、并发方案进行benchmark测试是验证假设的好办法。
### 不清楚何时使用channels或mutexes (#57)
了解 goroutine 之间的交互也可以在选择使用channels或mutexes时有所帮助。一般来说并行的 goroutine 需要同步因此需要使用mutexes。相反并发的 goroutine 通常需要协调和编排因此需要使用channels。
### 不明白竞态问题 (数据竞态 vs. 竞态条件 和 Go内存模型) (#58)
掌握并发意味着要认识到数据竞争data races和竞态条件race conditions是两个不同的概念。数据竞争指的是有多个goroutines同时访问相同内存区域时没有必要的同步控制且其中至少有一个goroutine是执行的写操作。同时要认识到没有发生数据竞争不代表程序的执行是确定性的、没问题的。当在某个特定的操作顺序或者特定的事件发生顺序下如果最终的行为是不可控的这就是竞态条件。
> ps数据竞争是竞态条件的子集竞态条件不仅局限于访存未同步它可以发生在更高的层面。`go test -race` 检测的是数据竞争需要同步来解决而开发者还需要关注面更广的竞态条件它需要对多个goroutines的执行进行编排。
理解 Go 的内存模型以及有关顺序和同步的底层保证是防止可能的数据竞争和竞态条件的关键。
### 不理解不同工作负载类型对并发的影响 (#59)
当创建一定数量的goroutines是需要考虑工作负载的类型。如果工作负载是CPU密集型的那么goroutines数量应该接近于 `GOMAXPROCS` 的值该值取决于主机处理器核心数。如果工作负载是IO密集型的goroutines数量就需要考虑多种因素比如外部系统考虑请求、响应速率
### 误解了Go contexts (#60)
Go 的上下文context也是 Go 并发编程的基石之一。上下文允许您携带截止时间、取消信号和键值列表。
## 并发编程: 实践
### 传递不合适的context (#61)
当我们传递了一个context我们需要知道这个context什么时候可以被取消这点很重要例如一个HTTP请求处理器在发送完响应后取消context。
> ps: 实际上context表达的是一个动作可以持续多久之后被停止。
### 启动了一个goroutine但是不知道它何时会停止 (#62)
避免goroutine泄漏要有这种意识当创建并启动一个goroutine的时候应该有对应的设计让它能正常退出。
### 不注意处理 goroutines 和 循环中的迭代变量 (#63)
为了避免goroutines和循环中的迭代变量问题可以考虑创建局部变量并将迭代变量赋值给局部变量或者goroutine调用带参数的函数将迭代变量值作为参数值传入来代替goroutine调用闭包。
### 使用select + channels 时误以为分支选择顺序是确定的 (#64)
要明白,`select` 多个channels时如果多个channels上的操作都就绪那么会随机选择一个 `case` 分支来执行因此要避免有分支选择顺序是从上到下的这种错误预设这可能会导致设计上的bug。
### 不正确使用通知 channels (#65)
发送通知时使用 `chan struct{}` 类型。
> ps: 先明白什么是通知channels一个通知channels指的是只是用来做通知而其中传递的数据没有意义或者理解成不传递数据的channels这种称为通知channels。其中传递的数据的类型struct{}更合适。
### 不使用 nil channels (#66)
使用 nil channels 应该是并发处理方式中的一部分,例如,它能够帮助禁用 `select` 语句中的特定的分支。
### 不清楚该如何确定 channel size (#67)
根据指定的场景仔细评估应该使用哪一种 channel 类型(带缓冲的,不带缓冲的)。只有不带缓冲的 channels 可以提供强同步保证。
使用带缓冲的 channels 时如果不确定 size 该如何设置可以先设为1如果有合理的理由再去指定 channels size。
> ps: 根据disruptor这个高性能内存消息队列的实践在某种读写pacing下队列要么满要么空不大可能处于某种介于中间的稳态。
### 忘记了字符串格式化可能带来的副作用(例如 etcd 数据竞争和死锁)(#68)
意识到字符串格式化可能会导致调用现有函数,这意味着需要注意可能的死锁和其他数据竞争问题。
> ps: 核心是要关注 `fmt.Sprintf` + `%v` 进行字符串格式化时 `%v` 具体到不同的类型值时,实际上执行的操作是什么。比如 `%v` 这个placeholder对应的值时一个 `context.Context`,那么会就遍历其通过 `context.WithValue` 附加在其中的 values这个过程可能涉及到数据竞争问题。书中提及的另一个导致死锁的案例本质上也是一样的问题只不过又额外牵扯到了 `sync.RWMutex` 不可重入的问题。
### 使用 append 不当导致数据竞争 (#69)
调用 `append` 不总是没有数据竞争的,因此不要在一个共享的 `slice` 上并发地执行 `append`
### 误用 mutexes 和 slices、maps (#70)
请记住 slices 和 maps 引用类型,有助于避免常见的数据竞争问题。
> ps: 这里实际是因为错误理解了 slices 和 maps导致写出了错误的拷贝 slices 和 maps 的代码,进而导致锁保护无效、出现数据竞争问题。
### 误用 `sync.WaitGroup` (#71)
正确地使用 `sync.WaitGroup` 需要在启动 goroutines 之前先调用 `Add` 方法。
### 忘记使用 `sync.Cond` (#72)
你可以使用 `sync.Cond` 向多个 goroutines 发送重复的通知。
### 不使用 `errgroup` (#73)
你可以使用 `errgroup` 包来同步一组 goroutines 并处理错误和上下文。
### 拷贝一个 `sync` 下的类型 (#74)
`sync` 包下的类型不应该被拷贝。
## 标准库
### 使用了错误的 time.Duration (#75)
注意有些函数接收一个 `time.Duration` 类型的参数时,尽管直接传递一个整数是可以的,但最好还是使用 time API 中的方法来传递 duration以避免可能造成的困惑、bug。
> ps: 重点是注意 time.Duration 定义的是 nanoseconds 数。
### `time.After` 和内存泄漏 (#76)
避免在重复执行很多次的函数 如循环中或HTTP处理函数中调用 `time.After`,这可以避免内存峰值消耗。由 `time.After` 创建的资源仅在计时器超时才会被释放。
### JSON处理中的常见错误 (#77)
* 类型嵌套导致的预料外的行为
要当心在Go结构体中嵌入字段这样做可能会导致诸如嵌入的 `time.Time` 字段实现 `json.Marshaler` 接口从而覆盖默认的json序列。
* JSON 和 单调时钟
当对两个 `time.Time` 类型值进行比较时,需要记住 `time.Time` 包含了一个墙上时钟wall clock和一个单调时钟 monotonic clock而使用 `==` 运算符进行比较时会同时比较这两个。
* Map 键对应值为 `any`
当提供一个map用来unmarshal JSON数据时为了避免不确定的value结构我们会使用 `any` 来作为value的类型而不是定义一个struct这种情况下需要记得数值默认会被转换为 `float64`
### 常见的 SQL 错误 (#78)
* 忘记了 `sql.Open` 并没有与db服务器建立实际连接
需要调用 `Ping` 或者 `PingContext` 方法来测试配置并确保数据库是可达的。
* 忘记了使用连接池
作为生产级别的应用,访问数据库时应该关注配置数据库连接池参数。
* 没有使用 prepared 语句
使用 SQL prepared 语句能够让查询更加高效和安全。
* 误处理 null 值
使用 `sql.NullXXX` 类型处理表中的可空列。
* 不处理行迭代时的错误
调用 `sql.Rows``Err` 方法来确保在准备下一个行时没有遗漏错误。
### 不关闭临时资源HTTP 请求体、`sql.Rows` 和 `os.File`) (#79)
最终要注意关闭所有实现 `io.Closer` 接口的结构体,以避免可能的泄漏。
### 响应HTTP请求后没有返回语句 (#80)
为了避免在HTTP处理函数中出现某些意外的问题如果想在发生 `http.Error` 后让HTTP处理函数停止那么就不要忘记使用`return`语句来阻止后续代码的执行。
### 直接使用默认的HTTP client和server (#81)
对于生产级别的应用不要使用默认的HTTP client和server实现。这些实现缺少超时和生产环境中应该强制使用的行为。
## 测试
### 不对测试进行分类 build tags, 环境变量,短模式)(#82)
对测试进行必要的分类,可以借助 build tags、环境变量以及短模式来使得测试过程更加高效。你可以使用 build tags 或环境变量来创建测试类别(例如单元测试与集成测试),并区分短测试与长时间测试,来决定执行哪种类型的。
> ps: 了解下go build tags以及 `go test -short`
### 不打开 race 开关 (#83)
打开 `-race` 开关在编写并发应用时非常重要。这能帮助你捕获可能的数据竞争,从而避免软件bug。
### 不打开测试的执行模式开关 (parallel 和 shuffle) (#84)
打开开关 `-parallel` 有助于加速测试的执行,特别是测试中包含一些需要长期运行的用例的时候。
打开开关 `-shuffle` 能够打乱测试用例执行的顺序避免一个测试依赖于某些不符合真实情况的预设有助于及早暴漏bug。
### 不使用表驱动的测试 (#85)
表驱动的测试是一种有效的方式,可以将一组相似的测试分组在一起,以避免代码重复和使未来的更新更容易处理。
### 在单元测试中执行sleep操作 (#86)
使用同步的方式、避免sleep来尽量减少测试的不稳定性和提高鲁棒性。如果无法使用同步手段,可以考虑重试的方式。
### 没有高效地处理 time API (#87)
理解如何处理使用 time API 的函数,是使测试更加稳定的另一种方式。您可以使用标准技术,例如将时间作为隐藏依赖项的一部分来处理,或者要求客户端提供时间。
### 不使用测试相关的工具包 (`httptest` 和 `iotest`) (#88)
这个 `httptest` 包对处理HTTP应用程序很有帮助。它提供了一组实用程序来测试客户端和服务器。
这个 `iotest` 包有助于编写 io.Reader 并测试应用程序是否能够容忍错误。
### [不正确的基准测试](https://teivah.medium.com/how-to-write-accurate-benchmarks-in-go-4266d7dd1a95) (#89)
* 不要重置或者暂停timer
使用 time 方法来保持基准测试的准确性。
* 做出错误的微基准测试假设
增加 `benchtime` 或者使用 `benchstat` 等工具可以有助于微基准测试。
小心微基准测试的结果,如果最终运行应用程序的系统与运行微基准测试的系统不同。
* 对编译期优化要足够小心
确保测试函数是否会产生一些副作用,防止编译器优化欺骗你得到的基准测试结果。
* 被观察者效应所欺骗
为了避免被观察者效应欺骗,强制重新创建CPU密集型函数使用的数据。
### 没有去探索go test所有的特性 (#90)
* 代码覆盖率
使用 `-coverprofile` 参数可以快速查看代码的测试覆盖情况,方便快速查看哪个部分需要更多的关注。
* 在一个不同包中执行测试
单元测试组织到一个独立的包中,对于对外层暴漏的接口,需要写一些测试用例。测试应该关注公开的行为,而非内部实现细节。
* Utility 函数
处理错误时,使用 `*testing.T` 变量而不是经典的 `if err != nil` 可以让代码更加简洁易读。
* 设置和销毁
你可以使用setup和teardown函数来配置一个复杂的环境比如在集成测试的情况下。
### 不使用模糊测试 (社区反馈错误)
模糊测试是一种高效的策略,使用它能检测出随机、意料外的和一些恶意的数据输入,来完成一些复杂的操作。
见: [@jeromedoucet](https://github.com/jeromedoucet)
## 优化技术
### 不理解CPU cache (#91)
* CPU架构
理解CPU缓存的使用对于优化CPU密集型应用很重要因为L1缓存比主存快50到100倍。
* Cache line
意识到 cache line 概念对于理解如何在数据密集型应用中组织数据非常关键。CPU 并不是一个一个字来获取内存。相反,它通常复制一个 64字节长度的 cache line。为了获得每个 cache line 的最大效用,需要实施空间局部性。
* 一系列struct元素构成的slice vs. 多个slice字段构成的struct
* 概率性的问题
提高CPU执行代码时的可预测性也是优化某些函数的一个有效方法。比如固定步长或连续访问对CPU来说是可预测的但非连续访问例如链表就是不可预测的。
* cache放置策略
要注意现代缓存是分区的set associative placement组相连映射要注意避免使用 `critical stride`,这种步长情况下只能利用 cache 的一小部分。
> critical stride这种类型的步长指的是内存访问的步长刚好等于 cache 大小。这种情况下,只有少部分 cacheline 被利用。
### 写的并发处理逻辑会导致false sharing (#92)
了解 CPU 缓存的较低层的 L1、L2 cache 不会在所有核间共享编写并发处理逻辑时能避免写出一些降低性能的问题比如伪共享false sharing。内存共享只是一种假象。
### 没有考虑指令级的并行 (#93)
使用指令级并行ILP优化代码的特定部分以允许CPU尽可能执行更多可以并行执行的指令。识别指令的数据依赖问题data hazards是主要步骤之一。
### 不了解数据对齐 (#94)
记住Go中基本类型与其自身大小对齐例如按降序从大到小重新组织结构体的字段可以形成更紧凑的结构体减少内存分配更好的空间局部性这有助于避免一些常见的错误。
### 不了解 stack vs. heap (#95)
了解堆和栈之间的区别是开发人员的核心知识点特别是要去优化一个Go程序时。栈分配的开销几乎为零而堆分配则较慢并且依赖GC来清理内存。
### 不知道如何减少内存分配次数 (API调整, compiler optimizations, and `sync.Pool`) (#96)
减少内存分配次数也是优化Go应用的一个重要方面。这可以通过不同的方式来实现,比如仔细设计API来避免不必要的拷贝以及使用 `sync.Pool` 来对待分配对象进行池化。
### 不注意使用内联 (#97)
使用快速路径的内联技术来更加有效地减少调用函数的摊销时间。
### [不使用Go问题诊断工具](https://medium.com/@teivah/profiling-and-execution-tracing-in-go-a5e646970f5b) (#98)
了解Go profilng工具、执行时tracer来辅助判断一个应用程序是否正常以及列出需要优化的部分。
### 不理解GC是如何工作的 (#99)
理解如何调优GC能够带来很多收益例如有助于更高效地处理突增的负载。
### 不了解Docker或者K8S对运行的Go应用的性能影响 (#100)
为了避免CPU throttlingCPU限频问题当我们在Docker和Kubernetes部署应用时要知道Go语言对CFS(完全公平调度器)无感知。

View file

@ -5,7 +5,7 @@ theme:
custom_dir: overrides
favicon: Go-Logo_Fuchsia.svg
language: en
logo: Go-Logo_Fuchsia.svg
logo: img/Go-Logo_White.svg
palette:
# Palette toggle for light mode
- scheme: default
@ -24,15 +24,17 @@ plugins:
- search
- social
extra:
analytics:
provider: google
property: G-HMY1HYDM93
alternate:
- name: English
link: /
lang: en
- name: Chinese (Simplified)
link: /chinese/
link: /zh/
lang: zh
social:
- icon: fontawesome/brands/twitter
link: https://twitter.com/teivah
generator: false
copyright: Copyright &copy; 2022 - 2023 Teiva Harsanyi

View file

@ -43,6 +43,16 @@
<script>__md_scope=new URL("/",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<script id="__analytics">function __md_analytics(){function n(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],n("js",new Date),n("config","G-HMY1HYDM93"),document.addEventListener("DOMContentLoaded",function(){document.forms.search&&document.forms.search.query.addEventListener("blur",function(){this.value&&n("event","search",{search_term:this.value})}),document$.subscribe(function(){var a=document.forms.feedback;if(void 0!==a)for(var e of a.querySelectorAll("[type=submit]"))e.addEventListener("click",function(e){e.preventDefault();var t=document.location.pathname,e=this.getAttribute("data-md-value");n("event","feedback",{page:t,data:e}),a.firstElementChild.disabled=!0;e=a.querySelector(".md-feedback__note [data-md-value='"+e+"']");e&&(e.hidden=!1)}),a.hidden=!1}),location$.subscribe(function(e){n("config","G-HMY1HYDM93",{page_path:e.pathname})})});var e=document.createElement("script");e.async=!0,e.src="https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93",document.getElementById("__analytics").insertAdjacentElement("afterEnd",e)}</script>
<script>"undefined"!=typeof __md_analytics&&__md_analytics()</script>
@ -82,7 +92,7 @@
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="/." title="100 Go Mistakes" class="md-header__button md-logo" aria-label="100 Go Mistakes" data-md-component="logo">
<img src="/Go-Logo_Fuchsia.svg" alt="logo">
<img src="/img/Go-Logo_White.svg" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
@ -149,7 +159,7 @@
</li>
<li class="md-select__item">
<a href="/chinese/" hreflang="zh" class="md-select__link">
<a href="/zh/" hreflang="zh" class="md-select__link">
Chinese (Simplified)
</a>
</li>
@ -237,7 +247,7 @@
<label class="md-nav__title" for="__drawer">
<a href="/." title="100 Go Mistakes" class="md-nav__button md-logo" aria-label="100 Go Mistakes" data-md-component="logo">
<img src="/Go-Logo_Fuchsia.svg" alt="logo">
<img src="/img/Go-Logo_White.svg" alt="logo">
</a>
100 Go Mistakes
@ -267,7 +277,7 @@
<span class="md-ellipsis">
100 Go Mistakes and How to Avoid Them
📖 Book Presentation
</span>
@ -286,7 +296,7 @@
<span class="md-ellipsis">
Go Jobs
❤️ Go Jobs
</span>
@ -305,7 +315,7 @@
<span class="md-ellipsis">
Common Go Mistakes
💡 Go Mistakes
</span>
@ -334,7 +344,7 @@
<span class="md-ellipsis">
Chinese
Zh
</span>
@ -344,7 +354,7 @@
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Chinese
Zh
</label>
<ul class="md-nav__list" data-md-scrollfix>
@ -354,11 +364,11 @@
<li class="md-nav__item">
<a href="/chinese/" class="md-nav__link">
<a href="/zh/" class="md-nav__link">
<span class="md-ellipsis">
Index
100个Go常见错误及如何避免
</span>
@ -419,6 +429,15 @@
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2022 - 2023 Teiva Harsanyi
</div>
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View file

@ -1,509 +0,0 @@
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="canonical" href="https://100go.co/chinese/">
<link rel="prev" href="../mistakes/">
<link rel="icon" href="../Go-Logo_Fuchsia.svg">
<meta name="generator" content="mkdocs-1.5.2, mkdocs-material-9.3.1">
<title>100 Go Mistakes</title>
<link rel="stylesheet" href="../assets/stylesheets/main.046329b4.min.css">
<link rel="stylesheet" href="../assets/stylesheets/palette.85d0ee34.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<meta property="og:type" content="website" >
<meta property="og:title" content="Index - 100 Go Mistakes" >
<meta property="og:description" content="None" >
<meta property="og:image" content="https://100go.co/assets/images/social/chinese/index.png" >
<meta property="og:image:type" content="image/png" >
<meta property="og:image:width" content="1200" >
<meta property="og:image:height" content="630" >
<meta property="og:url" content="https://100go.co/chinese/" >
<meta name="twitter:card" content="summary_large_image" >
<meta name="twitter:title" content="Index - 100 Go Mistakes" >
<meta name="twitter:description" content="None" >
<meta name="twitter:image" content="https://100go.co/assets/images/social/chinese/index.png" >
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="cyan" data-md-color-accent="indigo">
<script>var palette=__md_get("__palette");if(palette&&"object"==typeof palette.color)for(var key of Object.keys(palette.color))document.body.setAttribute("data-md-color-"+key,palette.color[key])</script>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href=".." title="100 Go Mistakes" class="md-header__button md-logo" aria-label="100 Go Mistakes" data-md-component="logo">
<img src="../Go-Logo_Fuchsia.svg" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2Z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
100 Go Mistakes
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Index
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="" data-md-color-scheme="default" data-md-color-primary="cyan" data-md-color-accent="indigo" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_2" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69Z"/></svg>
</label>
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="blue-grey" data-md-color-accent="indigo" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_2">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12c0-2.42-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69Z"/></svg>
</label>
</form>
<div class="md-header__option">
<div class="md-select">
<button class="md-header__button md-icon" aria-label="Select language">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m12.87 15.07-2.54-2.51.03-.03A17.52 17.52 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04M18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12m-2.62 7 1.62-4.33L19.12 17h-3.24Z"/></svg>
</button>
<div class="md-select__inner">
<ul class="md-select__list">
<li class="md-select__item">
<a href="/" hreflang="en" class="md-select__link">
English
</a>
</li>
<li class="md-select__item">
<a href="/chinese/" hreflang="zh" class="md-select__link">
Chinese (Simplified)
</a>
</li>
</ul>
</div>
</div>
</div>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41Z"/></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/teivah/100-go-mistakes" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
</div>
<div class="md-source__repository">
GitHub
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href=".." title="100 Go Mistakes" class="md-nav__button md-logo" aria-label="100 Go Mistakes" data-md-component="logo">
<img src="../Go-Logo_Fuchsia.svg" alt="logo">
</a>
100 Go Mistakes
</label>
<div class="md-nav__source">
<a href="https://github.com/teivah/100-go-mistakes" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
</div>
<div class="md-source__repository">
GitHub
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." class="md-nav__link">
<span class="md-ellipsis">
100 Go Mistakes and How to Avoid Them
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../jobs/" class="md-nav__link">
<span class="md-ellipsis">
Go Jobs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../mistakes/" class="md-nav__link">
<span class="md-ellipsis">
Common Go Mistakes
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" checked>
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
<span class="md-ellipsis">
Chinese
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Chinese
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Index
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1>Index</h1>
<p>TODO</p>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
</div>
<div class="md-social">
<a href="https://twitter.com/teivah" target="_blank" rel="noopener" title="twitter.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "..", "features": [], "search": "../assets/javascripts/workers/search.dfff1995.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script>
<script src="../assets/javascripts/bundle.dff1b7c8.min.js"></script>
</body>
</html>

60
site/img/Go-Logo_Aqua.svg Normal file
View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 254.5 225" style="enable-background:new 0 0 254.5 225;" xml:space="preserve">
<style type="text/css">
.st0{fill:#2DBCAF;}
.st1{fill:#5DC9E1;}
.st2{fill:#FDDD00;}
.st3{fill:#CE3262;}
.st4{fill:#00ACD7;}
.st5{fill:#FFFFFF;}
</style>
<g>
<g>
<g>
<g>
<path class="st0" d="M40.2,101.1c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l35.7,0c0.4,0,0.5,0.3,0.3,0.6
l-1.7,2.6c-0.2,0.3-0.7,0.6-1,0.6L40.2,101.1z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st0" d="M25.1,110.3c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l45.6,0c0.4,0,0.6,0.3,0.5,0.6
l-0.8,2.4c-0.1,0.4-0.5,0.6-0.9,0.6L25.1,110.3z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st0" d="M49.3,119.5c-0.4,0-0.5-0.3-0.3-0.6l1.4-2.5c0.2-0.3,0.6-0.6,1-0.6l20,0c0.4,0,0.6,0.3,0.6,0.7l-0.2,2.4
c0,0.4-0.4,0.7-0.7,0.7L49.3,119.5z"/>
</g>
</g>
</g>
<g>
<g id="CXHf1q_1_">
<g>
<g>
<path class="st0" d="M153.1,99.3c-6.3,1.6-10.6,2.8-16.8,4.4c-1.5,0.4-1.6,0.5-2.9-1c-1.5-1.7-2.6-2.8-4.7-3.8
c-6.3-3.1-12.4-2.2-18.1,1.5c-6.8,4.4-10.3,10.9-10.2,19c0.1,8,5.6,14.6,13.5,15.7c6.8,0.9,12.5-1.5,17-6.6
c0.9-1.1,1.7-2.3,2.7-3.7c-3.6,0-8.1,0-19.3,0c-2.1,0-2.6-1.3-1.9-3c1.3-3.1,3.7-8.3,5.1-10.9c0.3-0.6,1-1.6,2.5-1.6
c5.1,0,23.9,0,36.4,0c-0.2,2.7-0.2,5.4-0.6,8.1c-1.1,7.2-3.8,13.8-8.2,19.6c-7.2,9.5-16.6,15.4-28.5,17
c-9.8,1.3-18.9-0.6-26.9-6.6c-7.4-5.6-11.6-13-12.7-22.2c-1.3-10.9,1.9-20.7,8.5-29.3c7.1-9.3,16.5-15.2,28-17.3
c9.4-1.7,18.4-0.6,26.5,4.9c5.3,3.5,9.1,8.3,11.6,14.1C154.7,98.5,154.3,99,153.1,99.3z"/>
</g>
<g>
<path class="st0" d="M186.2,154.6c-9.1-0.2-17.4-2.8-24.4-8.8c-5.9-5.1-9.6-11.6-10.8-19.3c-1.8-11.3,1.3-21.3,8.1-30.2
c7.3-9.6,16.1-14.6,28-16.7c10.2-1.8,19.8-0.8,28.5,5.1c7.9,5.4,12.8,12.7,14.1,22.3c1.7,13.5-2.2,24.5-11.5,33.9
c-6.6,6.7-14.7,10.9-24,12.8C191.5,154.2,188.8,154.3,186.2,154.6z M210,114.2c-0.1-1.3-0.1-2.3-0.3-3.3
c-1.8-9.9-10.9-15.5-20.4-13.3c-9.3,2.1-15.3,8-17.5,17.4c-1.8,7.8,2,15.7,9.2,18.9c5.5,2.4,11,2.1,16.3-0.6
C205.2,129.2,209.5,122.8,210,114.2z"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

60
site/img/Go-Logo_Blue.svg Normal file
View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 254.5 225" style="enable-background:new 0 0 254.5 225;" xml:space="preserve">
<style type="text/css">
.st0{fill:#2DBCAF;}
.st1{fill:#5DC9E1;}
.st2{fill:#FDDD00;}
.st3{fill:#CE3262;}
.st4{fill:#00ACD7;}
.st5{fill:#FFFFFF;}
</style>
<g>
<g>
<g>
<g>
<path class="st4" d="M40.2,101.1c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l35.7,0c0.4,0,0.5,0.3,0.3,0.6
l-1.7,2.6c-0.2,0.3-0.7,0.6-1,0.6L40.2,101.1z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st4" d="M25.1,110.3c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l45.6,0c0.4,0,0.6,0.3,0.5,0.6
l-0.8,2.4c-0.1,0.4-0.5,0.6-0.9,0.6L25.1,110.3z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st4" d="M49.3,119.5c-0.4,0-0.5-0.3-0.3-0.6l1.4-2.5c0.2-0.3,0.6-0.6,1-0.6l20,0c0.4,0,0.6,0.3,0.6,0.7l-0.2,2.4
c0,0.4-0.4,0.7-0.7,0.7L49.3,119.5z"/>
</g>
</g>
</g>
<g>
<g id="CXHf1q_3_">
<g>
<g>
<path class="st4" d="M153.1,99.3c-6.3,1.6-10.6,2.8-16.8,4.4c-1.5,0.4-1.6,0.5-2.9-1c-1.5-1.7-2.6-2.8-4.7-3.8
c-6.3-3.1-12.4-2.2-18.1,1.5c-6.8,4.4-10.3,10.9-10.2,19c0.1,8,5.6,14.6,13.5,15.7c6.8,0.9,12.5-1.5,17-6.6
c0.9-1.1,1.7-2.3,2.7-3.7c-3.6,0-8.1,0-19.3,0c-2.1,0-2.6-1.3-1.9-3c1.3-3.1,3.7-8.3,5.1-10.9c0.3-0.6,1-1.6,2.5-1.6
c5.1,0,23.9,0,36.4,0c-0.2,2.7-0.2,5.4-0.6,8.1c-1.1,7.2-3.8,13.8-8.2,19.6c-7.2,9.5-16.6,15.4-28.5,17
c-9.8,1.3-18.9-0.6-26.9-6.6c-7.4-5.6-11.6-13-12.7-22.2c-1.3-10.9,1.9-20.7,8.5-29.3c7.1-9.3,16.5-15.2,28-17.3
c9.4-1.7,18.4-0.6,26.5,4.9c5.3,3.5,9.1,8.3,11.6,14.1C154.7,98.5,154.3,99,153.1,99.3z"/>
</g>
<g>
<path class="st4" d="M186.2,154.6c-9.1-0.2-17.4-2.8-24.4-8.8c-5.9-5.1-9.6-11.6-10.8-19.3c-1.8-11.3,1.3-21.3,8.1-30.2
c7.3-9.6,16.1-14.6,28-16.7c10.2-1.8,19.8-0.8,28.5,5.1c7.9,5.4,12.8,12.7,14.1,22.3c1.7,13.5-2.2,24.5-11.5,33.9
c-6.6,6.7-14.7,10.9-24,12.8C191.5,154.2,188.8,154.3,186.2,154.6z M210,114.2c-0.1-1.3-0.1-2.3-0.3-3.3
c-1.8-9.9-10.9-15.5-20.4-13.3c-9.3,2.1-15.3,8-17.5,17.4c-1.8,7.8,2,15.7,9.2,18.9c5.5,2.4,11,2.1,16.3-0.6
C205.2,129.2,209.5,122.8,210,114.2z"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 254.5 225" style="enable-background:new 0 0 254.5 225;" xml:space="preserve">
<style type="text/css">
.st0{fill:#2DBCAF;}
.st1{fill:#5DC9E1;}
.st2{fill:#FDDD00;}
.st3{fill:#CE3262;}
.st4{fill:#00ACD7;}
.st5{fill:#FFFFFF;}
</style>
<g>
<g>
<g>
<g>
<path class="st1" d="M40.2,101.1c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l35.7,0c0.4,0,0.5,0.3,0.3,0.6
l-1.7,2.6c-0.2,0.3-0.7,0.6-1,0.6L40.2,101.1z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st1" d="M25.1,110.3c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l45.6,0c0.4,0,0.6,0.3,0.5,0.6
l-0.8,2.4c-0.1,0.4-0.5,0.6-0.9,0.6L25.1,110.3z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st1" d="M49.3,119.5c-0.4,0-0.5-0.3-0.3-0.6l1.4-2.5c0.2-0.3,0.6-0.6,1-0.6l20,0c0.4,0,0.6,0.3,0.6,0.7l-0.2,2.4
c0,0.4-0.4,0.7-0.7,0.7L49.3,119.5z"/>
</g>
</g>
</g>
<g>
<g id="CXHf1q_7_">
<g>
<g>
<path class="st1" d="M153.1,99.3c-6.3,1.6-10.6,2.8-16.8,4.4c-1.5,0.4-1.6,0.5-2.9-1c-1.5-1.7-2.6-2.8-4.7-3.8
c-6.3-3.1-12.4-2.2-18.1,1.5c-6.8,4.4-10.3,10.9-10.2,19c0.1,8,5.6,14.6,13.5,15.7c6.8,0.9,12.5-1.5,17-6.6
c0.9-1.1,1.7-2.3,2.7-3.7c-3.6,0-8.1,0-19.3,0c-2.1,0-2.6-1.3-1.9-3c1.3-3.1,3.7-8.3,5.1-10.9c0.3-0.6,1-1.6,2.5-1.6
c5.1,0,23.9,0,36.4,0c-0.2,2.7-0.2,5.4-0.6,8.1c-1.1,7.2-3.8,13.8-8.2,19.6c-7.2,9.5-16.6,15.4-28.5,17
c-9.8,1.3-18.9-0.6-26.9-6.6c-7.4-5.6-11.6-13-12.7-22.2c-1.3-10.9,1.9-20.7,8.5-29.3c7.1-9.3,16.5-15.2,28-17.3
c9.4-1.7,18.4-0.6,26.5,4.9c5.3,3.5,9.1,8.3,11.6,14.1C154.7,98.5,154.3,99,153.1,99.3z"/>
</g>
<g>
<path class="st1" d="M186.2,154.6c-9.1-0.2-17.4-2.8-24.4-8.8c-5.9-5.1-9.6-11.6-10.8-19.3c-1.8-11.3,1.3-21.3,8.1-30.2
c7.3-9.6,16.1-14.6,28-16.7c10.2-1.8,19.8-0.8,28.5,5.1c7.9,5.4,12.8,12.7,14.1,22.3c1.7,13.5-2.2,24.5-11.5,33.9
c-6.6,6.7-14.7,10.9-24,12.8C191.5,154.2,188.8,154.3,186.2,154.6z M210,114.2c-0.1-1.3-0.1-2.3-0.3-3.3
c-1.8-9.9-10.9-15.5-20.4-13.3c-9.3,2.1-15.3,8-17.5,17.4c-1.8,7.8,2,15.7,9.2,18.9c5.5,2.4,11,2.1,16.3-0.6
C205.2,129.2,209.5,122.8,210,114.2z"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 254.5 225" style="enable-background:new 0 0 254.5 225;" xml:space="preserve">
<style type="text/css">
.st0{fill:#2DBCAF;}
.st1{fill:#5DC9E1;}
.st2{fill:#FDDD00;}
.st3{fill:#CE3262;}
.st4{fill:#00ACD7;}
.st5{fill:#FFFFFF;}
</style>
<g>
<g>
<g>
<g>
<path class="st5" d="M40.2,101.1c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l35.7,0c0.4,0,0.5,0.3,0.3,0.6
l-1.7,2.6c-0.2,0.3-0.7,0.6-1,0.6L40.2,101.1z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st5" d="M25.1,110.3c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l45.6,0c0.4,0,0.6,0.3,0.5,0.6
l-0.8,2.4c-0.1,0.4-0.5,0.6-0.9,0.6L25.1,110.3z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st5" d="M49.3,119.5c-0.4,0-0.5-0.3-0.3-0.6l1.4-2.5c0.2-0.3,0.6-0.6,1-0.6l20,0c0.4,0,0.6,0.3,0.6,0.7l-0.2,2.4
c0,0.4-0.4,0.7-0.7,0.7L49.3,119.5z"/>
</g>
</g>
</g>
<g>
<g id="CXHf1q_2_">
<g>
<g>
<path class="st5" d="M153.1,99.3c-6.3,1.6-10.6,2.8-16.8,4.4c-1.5,0.4-1.6,0.5-2.9-1c-1.5-1.7-2.6-2.8-4.7-3.8
c-6.3-3.1-12.4-2.2-18.1,1.5c-6.8,4.4-10.3,10.9-10.2,19c0.1,8,5.6,14.6,13.5,15.7c6.8,0.9,12.5-1.5,17-6.6
c0.9-1.1,1.7-2.3,2.7-3.7c-3.6,0-8.1,0-19.3,0c-2.1,0-2.6-1.3-1.9-3c1.3-3.1,3.7-8.3,5.1-10.9c0.3-0.6,1-1.6,2.5-1.6
c5.1,0,23.9,0,36.4,0c-0.2,2.7-0.2,5.4-0.6,8.1c-1.1,7.2-3.8,13.8-8.2,19.6c-7.2,9.5-16.6,15.4-28.5,17
c-9.8,1.3-18.9-0.6-26.9-6.6c-7.4-5.6-11.6-13-12.7-22.2c-1.3-10.9,1.9-20.7,8.5-29.3c7.1-9.3,16.5-15.2,28-17.3
c9.4-1.7,18.4-0.6,26.5,4.9c5.3,3.5,9.1,8.3,11.6,14.1C154.7,98.5,154.3,99,153.1,99.3z"/>
</g>
<g>
<path class="st5" d="M186.2,154.6c-9.1-0.2-17.4-2.8-24.4-8.8c-5.9-5.1-9.6-11.6-10.8-19.3c-1.8-11.3,1.3-21.3,8.1-30.2
c7.3-9.6,16.1-14.6,28-16.7c10.2-1.8,19.8-0.8,28.5,5.1c7.9,5.4,12.8,12.7,14.1,22.3c1.7,13.5-2.2,24.5-11.5,33.9
c-6.6,6.7-14.7,10.9-24,12.8C191.5,154.2,188.8,154.3,186.2,154.6z M210,114.2c-0.1-1.3-0.1-2.3-0.3-3.3
c-1.8-9.9-10.9-15.5-20.4-13.3c-9.3,2.1-15.3,8-17.5,17.4c-1.8,7.8,2,15.7,9.2,18.9c5.5,2.4,11,2.1,16.3-0.6
C205.2,129.2,209.5,122.8,210,114.2z"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 254.5 225" style="enable-background:new 0 0 254.5 225;" xml:space="preserve">
<style type="text/css">
.st0{fill:#2DBCAF;}
.st1{fill:#5DC9E1;}
.st2{fill:#FDDD00;}
.st3{fill:#CE3262;}
.st4{fill:#00ACD7;}
.st5{fill:#FFFFFF;}
</style>
<g>
<g>
<g>
<g>
<path class="st2" d="M40.2,101.1c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l35.7,0c0.4,0,0.5,0.3,0.3,0.6
l-1.7,2.6c-0.2,0.3-0.7,0.6-1,0.6L40.2,101.1z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st2" d="M25.1,110.3c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l45.6,0c0.4,0,0.6,0.3,0.5,0.6
l-0.8,2.4c-0.1,0.4-0.5,0.6-0.9,0.6L25.1,110.3z"/>
</g>
</g>
</g>
<g>
<g>
<g>
<path class="st2" d="M49.3,119.5c-0.4,0-0.5-0.3-0.3-0.6l1.4-2.5c0.2-0.3,0.6-0.6,1-0.6l20,0c0.4,0,0.6,0.3,0.6,0.7l-0.2,2.4
c0,0.4-0.4,0.7-0.7,0.7L49.3,119.5z"/>
</g>
</g>
</g>
<g>
<g id="CXHf1q_6_">
<g>
<g>
<path class="st2" d="M153.1,99.3c-6.3,1.6-10.6,2.8-16.8,4.4c-1.5,0.4-1.6,0.5-2.9-1c-1.5-1.7-2.6-2.8-4.7-3.8
c-6.3-3.1-12.4-2.2-18.1,1.5c-6.8,4.4-10.3,10.9-10.2,19c0.1,8,5.6,14.6,13.5,15.7c6.8,0.9,12.5-1.5,17-6.6
c0.9-1.1,1.7-2.3,2.7-3.7c-3.6,0-8.1,0-19.3,0c-2.1,0-2.6-1.3-1.9-3c1.3-3.1,3.7-8.3,5.1-10.9c0.3-0.6,1-1.6,2.5-1.6
c5.1,0,23.9,0,36.4,0c-0.2,2.7-0.2,5.4-0.6,8.1c-1.1,7.2-3.8,13.8-8.2,19.6c-7.2,9.5-16.6,15.4-28.5,17
c-9.8,1.3-18.9-0.6-26.9-6.6c-7.4-5.6-11.6-13-12.7-22.2c-1.3-10.9,1.9-20.7,8.5-29.3c7.1-9.3,16.5-15.2,28-17.3
c9.4-1.7,18.4-0.6,26.5,4.9c5.3,3.5,9.1,8.3,11.6,14.1C154.7,98.5,154.3,99,153.1,99.3z"/>
</g>
<g>
<path class="st2" d="M186.2,154.6c-9.1-0.2-17.4-2.8-24.4-8.8c-5.9-5.1-9.6-11.6-10.8-19.3c-1.8-11.3,1.3-21.3,8.1-30.2
c7.3-9.6,16.1-14.6,28-16.7c10.2-1.8,19.8-0.8,28.5,5.1c7.9,5.4,12.8,12.7,14.1,22.3c1.7,13.5-2.2,24.5-11.5,33.9
c-6.6,6.7-14.7,10.9-24,12.8C191.5,154.2,188.8,154.3,186.2,154.6z M210,114.2c-0.1-1.3-0.1-2.3-0.3-3.3
c-1.8-9.9-10.9-15.5-20.4-13.3c-9.3,2.1-15.3,8-17.5,17.4c-1.8,7.8,2,15.7,9.2,18.9c5.5,2.4,11,2.1,16.3-0.6
C205.2,129.2,209.5,122.8,210,114.2z"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

Before

Width:  |  Height:  |  Size: 402 KiB

After

Width:  |  Height:  |  Size: 402 KiB

View file

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 76 KiB

View file

Before

Width:  |  Height:  |  Size: 3.5 MiB

After

Width:  |  Height:  |  Size: 3.5 MiB

View file

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

View file

@ -47,13 +47,23 @@
<script>__md_scope=new URL(".",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<script id="__analytics">function __md_analytics(){function n(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],n("js",new Date),n("config","G-HMY1HYDM93"),document.addEventListener("DOMContentLoaded",function(){document.forms.search&&document.forms.search.query.addEventListener("blur",function(){this.value&&n("event","search",{search_term:this.value})}),document$.subscribe(function(){var a=document.forms.feedback;if(void 0!==a)for(var e of a.querySelectorAll("[type=submit]"))e.addEventListener("click",function(e){e.preventDefault();var t=document.location.pathname,e=this.getAttribute("data-md-value");n("event","feedback",{page:t,data:e}),a.firstElementChild.disabled=!0;e=a.querySelector(".md-feedback__note [data-md-value='"+e+"']");e&&(e.hidden=!1)}),a.hidden=!1}),location$.subscribe(function(e){n("config","G-HMY1HYDM93",{page_path:e.pathname})})});var e=document.createElement("script");e.async=!0,e.src="https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93",document.getElementById("__analytics").insertAdjacentElement("afterEnd",e)}</script>
<script>"undefined"!=typeof __md_analytics&&__md_analytics()</script>
<meta property="og:type" content="website" >
<meta property="og:title" content="100 Go Mistakes and How to Avoid Them" >
<meta property="og:title" content="📖 Book Presentation" >
<meta property="og:description" content="None" >
@ -69,7 +79,7 @@
<meta name="twitter:card" content="summary_large_image" >
<meta name="twitter:title" content="100 Go Mistakes and How to Avoid Them" >
<meta name="twitter:title" content="📖 Book Presentation" >
<meta name="twitter:description" content="None" >
@ -117,7 +127,7 @@
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="." title="100 Go Mistakes" class="md-header__button md-logo" aria-label="100 Go Mistakes" data-md-component="logo">
<img src="Go-Logo_Fuchsia.svg" alt="logo">
<img src="img/Go-Logo_White.svg" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
@ -134,7 +144,7 @@
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
100 Go Mistakes and How to Avoid Them
📖 Book Presentation
</span>
</div>
@ -184,7 +194,7 @@
</li>
<li class="md-select__item">
<a href="/chinese/" hreflang="zh" class="md-select__link">
<a href="/zh/" hreflang="zh" class="md-select__link">
Chinese (Simplified)
</a>
</li>
@ -272,7 +282,7 @@
<label class="md-nav__title" for="__drawer">
<a href="." title="100 Go Mistakes" class="md-nav__button md-logo" aria-label="100 Go Mistakes" data-md-component="logo">
<img src="Go-Logo_Fuchsia.svg" alt="logo">
<img src="img/Go-Logo_White.svg" alt="logo">
</a>
100 Go Mistakes
@ -311,7 +321,7 @@
<span class="md-ellipsis">
100 Go Mistakes and How to Avoid Them
📖 Book Presentation
</span>
@ -322,7 +332,7 @@
<span class="md-ellipsis">
100 Go Mistakes and How to Avoid Them
📖 Book Presentation
</span>
@ -436,7 +446,7 @@
<span class="md-ellipsis">
Go Jobs
❤️ Go Jobs
</span>
@ -455,7 +465,7 @@
<span class="md-ellipsis">
Common Go Mistakes
💡 Go Mistakes
</span>
@ -484,7 +494,7 @@
<span class="md-ellipsis">
Chinese
Zh
</span>
@ -494,7 +504,7 @@
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Chinese
Zh
</label>
<ul class="md-nav__list" data-md-scrollfix>
@ -504,11 +514,11 @@
<li class="md-nav__item">
<a href="chinese/" class="md-nav__link">
<a href="zh/" class="md-nav__link">
<span class="md-ellipsis">
Index
100个Go常见错误及如何避免
</span>
@ -646,7 +656,7 @@
<h1 id="book-presentation">📖 Book Presentation</h1>
<p>Source code and community space of <em>100 Go Mistakes and How to Avoid Them</em>, published by Manning in 2022.</p>
<p><img alt="" src="cover.png" /></p>
<p><img alt="" src="img/cover.png" /></p>
<h2 id="book-description">Book Description</h2>
<p>If you're a Go developer looking to improve your skills, this book is for you. With a focus on practical examples, <em>100 Go Mistakes and How to Avoid Them</em> covers a wide range of topics from concurrency and error handling to testing and code organization. You'll learn to write more idiomatic, efficient, and maintainable code and become a proficient Go developer.</p>
<h3 id="quotes">Quotes</h3>
@ -708,6 +718,8 @@
</ul>
@ -726,6 +738,15 @@
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2022 - 2023 Teiva Harsanyi
</div>
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>

View file

@ -49,13 +49,23 @@
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<script id="__analytics">function __md_analytics(){function n(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],n("js",new Date),n("config","G-HMY1HYDM93"),document.addEventListener("DOMContentLoaded",function(){document.forms.search&&document.forms.search.query.addEventListener("blur",function(){this.value&&n("event","search",{search_term:this.value})}),document$.subscribe(function(){var a=document.forms.feedback;if(void 0!==a)for(var e of a.querySelectorAll("[type=submit]"))e.addEventListener("click",function(e){e.preventDefault();var t=document.location.pathname,e=this.getAttribute("data-md-value");n("event","feedback",{page:t,data:e}),a.firstElementChild.disabled=!0;e=a.querySelector(".md-feedback__note [data-md-value='"+e+"']");e&&(e.hidden=!1)}),a.hidden=!1}),location$.subscribe(function(e){n("config","G-HMY1HYDM93",{page_path:e.pathname})})});var e=document.createElement("script");e.async=!0,e.src="https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93",document.getElementById("__analytics").insertAdjacentElement("afterEnd",e)}</script>
<script>"undefined"!=typeof __md_analytics&&__md_analytics()</script>
<meta property="og:type" content="website" >
<meta property="og:title" content="Go Jobs - 100 Go Mistakes" >
<meta property="og:title" content="❤️ Go Jobs - 100 Go Mistakes" >
<meta property="og:description" content="None" >
@ -71,7 +81,7 @@
<meta name="twitter:card" content="summary_large_image" >
<meta name="twitter:title" content="Go Jobs - 100 Go Mistakes" >
<meta name="twitter:title" content="❤️ Go Jobs - 100 Go Mistakes" >
<meta name="twitter:description" content="None" >
@ -119,7 +129,7 @@
<nav class="md-header__inner md-grid" aria-label="Header">
<a href=".." title="100 Go Mistakes" class="md-header__button md-logo" aria-label="100 Go Mistakes" data-md-component="logo">
<img src="../Go-Logo_Fuchsia.svg" alt="logo">
<img src="../img/Go-Logo_White.svg" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
@ -136,7 +146,7 @@
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Go Jobs
❤️ Go Jobs
</span>
</div>
@ -186,7 +196,7 @@
</li>
<li class="md-select__item">
<a href="/chinese/" hreflang="zh" class="md-select__link">
<a href="/zh/" hreflang="zh" class="md-select__link">
Chinese (Simplified)
</a>
</li>
@ -274,7 +284,7 @@
<label class="md-nav__title" for="__drawer">
<a href=".." title="100 Go Mistakes" class="md-nav__button md-logo" aria-label="100 Go Mistakes" data-md-component="logo">
<img src="../Go-Logo_Fuchsia.svg" alt="logo">
<img src="../img/Go-Logo_White.svg" alt="logo">
</a>
100 Go Mistakes
@ -304,7 +314,7 @@
<span class="md-ellipsis">
100 Go Mistakes and How to Avoid Them
📖 Book Presentation
</span>
@ -332,7 +342,7 @@
<span class="md-ellipsis">
Go Jobs
❤️ Go Jobs
</span>
@ -352,7 +362,7 @@
<span class="md-ellipsis">
Common Go Mistakes
💡 Go Mistakes
</span>
@ -381,7 +391,7 @@
<span class="md-ellipsis">
Chinese
Zh
</span>
@ -391,7 +401,7 @@
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Chinese
Zh
</label>
<ul class="md-nav__list" data-md-scrollfix>
@ -401,11 +411,11 @@
<li class="md-nav__item">
<a href="../chinese/" class="md-nav__link">
<a href="../zh/" class="md-nav__link">
<span class="md-ellipsis">
Index
100个Go常见错误及如何避免
</span>
@ -459,15 +469,11 @@
<h1 id="go-jobs">❤️ Go Jobs</h1>
<p>Is your company hiring? <a href="https://github.com/sponsors/teivah/sponsorships?sponsor=teivah&amp;tier_id=316526&amp;preview=true">Sponsor</a> this repository and let Go developers know your opportunities in this section (traffic: +400 unique visitor per week).</p>
<p>For example:</p>
<h1 id="company-remote-usa-96000-to-120000-a-year">[Company] Remote (USA) - $96,000 to $120,000 a year</h1>
<h2 id="job-description">Job Description</h2>
<p>...</p>
<h2 id="qualifications">Qualifications</h2>
<p>...</p>
<p>Is your company hiring? <a href="https://github.com/sponsors/teivah/sponsorships?sponsor=teivah&amp;tier_id=316526&amp;preview=true">Sponsor</a> this repository and let a significant audience of Go developers know about your opportunities in this section (book sales: +8k, website traffic: +2000 views and +400 unique visitors per week).</p>
@ -486,6 +492,15 @@
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2022 - 2023 Teiva Harsanyi
</div>
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>

View file

@ -14,7 +14,7 @@
<link rel="prev" href="../jobs/">
<link rel="next" href="../chinese/">
<link rel="next" href="../zh/">
<link rel="icon" href="../Go-Logo_Fuchsia.svg">
@ -49,13 +49,23 @@
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<script id="__analytics">function __md_analytics(){function n(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],n("js",new Date),n("config","G-HMY1HYDM93"),document.addEventListener("DOMContentLoaded",function(){document.forms.search&&document.forms.search.query.addEventListener("blur",function(){this.value&&n("event","search",{search_term:this.value})}),document$.subscribe(function(){var a=document.forms.feedback;if(void 0!==a)for(var e of a.querySelectorAll("[type=submit]"))e.addEventListener("click",function(e){e.preventDefault();var t=document.location.pathname,e=this.getAttribute("data-md-value");n("event","feedback",{page:t,data:e}),a.firstElementChild.disabled=!0;e=a.querySelector(".md-feedback__note [data-md-value='"+e+"']");e&&(e.hidden=!1)}),a.hidden=!1}),location$.subscribe(function(e){n("config","G-HMY1HYDM93",{page_path:e.pathname})})});var e=document.createElement("script");e.async=!0,e.src="https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93",document.getElementById("__analytics").insertAdjacentElement("afterEnd",e)}</script>
<script>"undefined"!=typeof __md_analytics&&__md_analytics()</script>
<meta property="og:type" content="website" >
<meta property="og:title" content="Common Go Mistakes - 100 Go Mistakes" >
<meta property="og:title" content="💡 Go Mistakes - 100 Go Mistakes" >
<meta property="og:description" content="None" >
@ -71,7 +81,7 @@
<meta name="twitter:card" content="summary_large_image" >
<meta name="twitter:title" content="Common Go Mistakes - 100 Go Mistakes" >
<meta name="twitter:title" content="💡 Go Mistakes - 100 Go Mistakes" >
<meta name="twitter:description" content="None" >
@ -119,7 +129,7 @@
<nav class="md-header__inner md-grid" aria-label="Header">
<a href=".." title="100 Go Mistakes" class="md-header__button md-logo" aria-label="100 Go Mistakes" data-md-component="logo">
<img src="../Go-Logo_Fuchsia.svg" alt="logo">
<img src="../img/Go-Logo_White.svg" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
@ -136,7 +146,7 @@
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Common Go Mistakes
💡 Go Mistakes
</span>
</div>
@ -186,7 +196,7 @@
</li>
<li class="md-select__item">
<a href="/chinese/" hreflang="zh" class="md-select__link">
<a href="/zh/" hreflang="zh" class="md-select__link">
Chinese (Simplified)
</a>
</li>
@ -274,7 +284,7 @@
<label class="md-nav__title" for="__drawer">
<a href=".." title="100 Go Mistakes" class="md-nav__button md-logo" aria-label="100 Go Mistakes" data-md-component="logo">
<img src="../Go-Logo_Fuchsia.svg" alt="logo">
<img src="../img/Go-Logo_White.svg" alt="logo">
</a>
100 Go Mistakes
@ -304,7 +314,7 @@
<span class="md-ellipsis">
100 Go Mistakes and How to Avoid Them
📖 Book Presentation
</span>
@ -323,7 +333,7 @@
<span class="md-ellipsis">
Go Jobs
❤️ Go Jobs
</span>
@ -351,7 +361,7 @@
<span class="md-ellipsis">
Common Go Mistakes
💡 Go Mistakes
</span>
@ -362,7 +372,7 @@
<span class="md-ellipsis">
Common Go Mistakes
💡 Go Mistakes
</span>
@ -1281,7 +1291,7 @@
<span class="md-ellipsis">
Chinese
Zh
</span>
@ -1291,7 +1301,7 @@
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Chinese
Zh
</label>
<ul class="md-nav__list" data-md-scrollfix>
@ -1301,11 +1311,11 @@
<li class="md-nav__item">
<a href="../chinese/" class="md-nav__link">
<a href="../zh/" class="md-nav__link">
<span class="md-ellipsis">
Index
100个Go常见错误及如何避免
</span>
@ -2243,7 +2253,7 @@
<!-- TODO Include chapter-1.md -->
<p><img alt="" src="../inside-cover.png" /></p>
<p><img alt="" src="../img/inside-cover.png" /></p>
<h2 id="code-and-project-organization">Code and Project Organization</h2>
<h3 id="unintended-variable-shadowing-1">Unintended variable shadowing (#1)</h3>
<p><strong>TL;DR</strong>: Avoiding shadowed variables can help prevent mistakes like referencing the wrong variable or confusing readers.</p>
@ -2255,34 +2265,36 @@
<ul>
<li>When an <code>if</code> block returns, we should omit the <code>else</code> block in all cases. For example, we shouldnt write:</li>
</ul>
<p><code>go
if foo() {
// ...
return true
} else {
// ...
}</code></p>
<pre><code class="language-go">if foo() {
// ...
return true
} else {
// ...
}
</code></pre>
<p>Instead, we omit the <code>else</code> block like this:</p>
<p><code>go
if foo() {
// ...
return true
}
// ...</code>
* We can also follow this logic with a non-happy path:</p>
<p><code>go
if s != "" {
// ...
} else {
return errors.New("empty string")
}</code></p>
<pre><code class="language-go">if foo() {
// ...
return true
}
// ...
</code></pre>
<ul>
<li>We can also follow this logic with a non-happy path:</li>
</ul>
<pre><code class="language-go">if s != &quot;&quot; {
// ...
} else {
return errors.New(&quot;empty string&quot;)
}
</code></pre>
<p>Here, an empty <code>s</code> represents the non-happy path. Hence, we should flip the
condition like so:</p>
<p><code>go
if s == "" {
return errors.New("empty string")
}
// ...</code></p>
<pre><code class="language-go">if s == &quot;&quot; {
return errors.New(&quot;empty string&quot;)
}
// ...
</code></pre>
<p>Writing readable code is an important challenge for every developer. Striving to reduce the number of nested blocks, aligning the happy path on the left, and returning as early as possible are concrete means to improve our codes readability.</p>
<p><a href="https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/2-nested-code/main.go">Source code</a></p>
<h3 id="misusing-init-functions-3">Misusing init functions (#3)</h3>
@ -2355,7 +2367,7 @@ promoted to <code>Foo</code>. Therefore, Baz becomes available from Foo.</p>
<p>Although there are different implementations with minor variations, the main idea is as follows:
* An unexported struct holds the configuration: options.
* Each option is a function that returns the same type: <code>type Option func(options *options)</code> error. For example, <code>WithPort</code> accepts an <code>int</code> argument that represents the port and returns an <code>Option</code> type that represents how to update the <code>options</code> struct.</p>
<p><img alt="" src="../options.png" /></p>
<p><img alt="" src="../img/options.png" /></p>
<pre><code class="language-go">type options struct {
port *int
}
@ -2691,7 +2703,7 @@ len=6
</ul>
<p>Lets start with the last observation. We already mentioned that len returns the num- ber of bytes in a string, not the number of runes. Because we assigned a string literal to <code>s</code>, <code>s</code> is a UTF-8 string. Meanwhile, the special character "ê" isnt encoded in a single byte; it requires 2 bytes. Therefore, calling <code>len(s)</code> returns 6.</p>
<p>Meanwhile, in the previous example, we have to understand that we don't iterate over each rune; instead, we iterate over each starting index of a rune:</p>
<p><img alt="" src="../rune.png" /></p>
<p><img alt="" src="../img/rune.png" /></p>
<p>Printing <code>s[i]</code> doesnt print the ith rune; it prints the UTF-8 representation of the byte at index <code>i</code>. Hence, we printed "hÃllo" instead of "hêllo".</p>
<p>If we want to print all the different runes, we can either use the value element of the <code>range</code> operator:</p>
<pre><code class="language-go">s := &quot;hêllo&quot;
@ -2719,7 +2731,7 @@ fmt.Printf(&quot;%c\n&quot;, r) // o
<pre><code class="language-cgo">fmt.Println(strings.TrimRight(&quot;123oxo&quot;, &quot;xo&quot;))
</code></pre>
<p>The example prints 123:</p>
<p><img alt="" src="../trim.png" /></p>
<p><img alt="" src="../img/trim.png" /></p>
<p>Conversely, <code>strings.TrimLeft</code> removes all the leading runes contained in a set.</p>
<p>On the other side, <code>strings.TrimSuffix</code> / <code>strings.TrimPrefix</code> returns a string without the provided trailing suffix / prefix.</p>
<p><a href="https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/38-trim/main.go">Source code</a></p>
@ -3241,6 +3253,8 @@ _ = notify()
<p><strong>TL;DR</strong>: To help avoid CPU throttling when deployed in Docker and Kubernetes, keep in mind that Go isnt CFS-aware.</p>
@ -3259,6 +3273,15 @@ _ = notify()
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2022 - 2023 Teiva Harsanyi
</div>
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>

File diff suppressed because one or more lines are too long

View file

@ -16,7 +16,7 @@
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://100go.co/chinese/</loc>
<loc>https://100go.co/zh/</loc>
<lastmod>2023-09-12</lastmod>
<changefreq>daily</changefreq>
</url>

Binary file not shown.

2611
site/zh/index.html Normal file

File diff suppressed because it is too large Load diff