Bài viết này thực hiện (hoặc lụm bài về đăng câu like từ các trang khác) bởi Việt Lâm Coder một YOUTUBER có tâm và đẹp trai siêu cấp vô địch zũ trụ.
Mục lục
Sử dụng một GOPATH duy nhất
Sử dụng đồng thời nhiều GOPATH
sẽ không giúp cho hệ thống mở rộng tốt. Bản thân GOPATH
đã rất độc lập (thông qua import path). Việc sử dụng một lúc nhiều GOPATH
sẽ đem lại hiệu ứng phụ, ví dụ như nhiều phiên bản khác nhau cho một package. Bạn có thể update version của một package tại chỗ này nhưng lại quên chỗ khác. Cá nhân tôi chưa từng thấy một project nào lại cần nhiều GOPATH
khác nhau.
Một số dự án lớn như camlistore cũng vendoring bằng cách đóng băng tất cả các phụ thuộc vào một folder sử dụng godep. Điều đó có nghĩa là ngay cả các dự án đó cũng sử dụng một và chỉ một GOPATH
.
Sử dụng hàm khi dùng select bên trong vòng for
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<span class="hljs-keyword">func</span> main() { L: <span class="hljs-keyword">for</span> { <span class="hljs-keyword">select</span> { <span class="hljs-keyword">case</span> t1 := <-time.After(time.Second): fmt.Println(<span class="hljs-string">"hello"</span>, t1) <span class="hljs-keyword">if</span> t1.Second()<span class="hljs-number">%4</span> ==<span class="hljs-number"> 0</span> { <span class="hljs-keyword">break</span> L } } } fmt.Println(<span class="hljs-string">"ending"</span>) } |
L
để break bởi nếu chỉ dùng break đơn thuần thì sẽ không thoát ra khỏi cả vòng for.Mặc dù đây là cách dùng đúng cho label, tuy nhiên cá nhân tôi không thích cách dùng này lắm. Nếu đoạn code được viết lại như sau thì sẽ không cần dùng label nữa
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<span class="hljs-function">func <span class="hljs-title">foo</span><span class="hljs-params">()</span> </span>{ <span class="hljs-keyword">for</span> { <span class="hljs-keyword">select</span> { <span class="hljs-keyword">case</span> t1 := <-time.After(time.Second): fmt.Println(<span class="hljs-string">"hello"</span>, t1) <span class="hljs-keyword">if</span> t1.Second()%<span class="hljs-number">4</span> == <span class="hljs-number">0</span> { <span class="hljs-keyword">return</span> } } } } <span class="hljs-function">func <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{ foo() fmt.Println(<span class="hljs-string">"ending"</span>) } |
Khi khởi tạo struct, hãy sử dụng tên của thuộc tính
Giả sử chúng ta có struct dưới đây
1 2 3 4 5 |
<span class="hljs-keyword">type</span> T <span class="hljs-keyword">struct</span> { Foo <span class="hljs-typename">string</span> Bar <span class="hljs-typename">int</span> } |
Có 2 cách để khởi tạo T, và đều đem lại kết quả như nhau
1 2 |
t := T{<span class="hljs-string">"example"</span>,<span class="hljs-number"> 123</span>} |
1 2 |
t := T{Foo: <span class="hljs-string">"example"</span>, Bar:<span class="hljs-number"> 123</span>} |
Mặc dù đem lại kết quả giống nhau, tuy nhiên hãy hình dung ta thêm thuộc tính vào T
1 2 3 4 5 6 |
<span class="hljs-keyword">type</span> T <span class="hljs-keyword">struct</span> { Foo <span class="hljs-typename">string</span> Bar <span class="hljs-typename">int</span> Qux <span class="hljs-typename">string</span> } |
Khi đó thì cách không chỉ định tên của thuộc tính sẽ compile error (lỗi không đủ giá trị)
Hãy chia làm nhiều dòng khi khởi tạo struct
Thay vì viết là
1 2 |
T{Foo: <span class="hljs-string">"example"</span>, Bar:someLongVariable, Qux:anotherLongVariable, B: forgetToAddThisToo} |
thì hãy viết
1 2 3 4 5 6 7 |
T{ Foo: <span class="hljs-string">"example"</span>, Bar: someLongVariable, Qux: anotherLongVariable, B: forgetToAddThisToo, } |
Thêm hàm String()
vào enum kiểu int
Giả sử chúng ta có kiểu enum như sau
1 2 3 4 5 6 7 8 9 |
<span class="hljs-keyword">type</span> State <span class="hljs-typename">int</span> <span class="hljs-keyword">const</span> ( Running State = <span class="hljs-constant">iota</span> Stopped Rebooting Terminated ) |
Tuy nhiên khi sử dụng trong code thì sẽ khó phân biệt kiểu, do đó nếu chúng ta thêm method
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<span class="hljs-func"><span class="hljs-keyword">func</span> <span class="hljs-params">(s State)</span> <span class="hljs-title">String</span><span class="hljs-params">()</span> <span class="hljs-title">string</span> </span>{ <span class="hljs-keyword">switch</span> s { <span class="hljs-keyword">case</span> <span class="hljs-type">Running</span>: <span class="hljs-keyword">return</span> <span class="hljs-string">"Running"</span> <span class="hljs-keyword">case</span> <span class="hljs-type">Stopped</span>: <span class="hljs-keyword">return</span> <span class="hljs-string">"Stopped"</span> <span class="hljs-keyword">case</span> <span class="hljs-type">Rebooting</span>: <span class="hljs-keyword">return</span> <span class="hljs-string">"Rebooting"</span> <span class="hljs-keyword">case</span> <span class="hljs-type">Terminated</span>: <span class="hljs-keyword">return</span> <span class="hljs-string">"Terminated"</span> <span class="hljs-keyword">default</span>: <span class="hljs-keyword">return</span> <span class="hljs-string">"Unknown"</span> } } |
thì khi print ra sẽ hiển thị s là “Running” thay vì 0
Khi sử dụng iota hãy nhớ thêm +1
Giả sử chúng ta có struct như sau:
1 2 3 4 5 6 |
<span class="hljs-typedef"><span class="hljs-keyword">type</span> <span class="hljs-type">T</span> struct <span class="hljs-container">{ <span class="hljs-type">Name</span> <span class="hljs-title">string</span> <span class="hljs-type">Port</span> <span class="hljs-title">int</span> <span class="hljs-type">State</span> <span class="hljs-type">State</span> }</span></span> |
và struct này được sử dụng
1 2 3 4 5 |
<span class="hljs-keyword">func</span> main() { t := T{Name: <span class="hljs-string">"example"</span>, Port:<span class="hljs-number"> 6666</span>} fmt.Printf(<span class="hljs-string">"%+v\n"</span>, t) <span class="hljs-comment">// --> "{Name:example Port:6666 State:Running}"</span> } |
Bạn có thể thấy chúng ta đã quên mất khởi tạo giá trị State, và nó ngẫu nhiên nhận giá trị Running, có vẻ là một giả định không hề tốt
Vậy điều cần làm là thay vì bắt đầu enum từ 0, chúng ta hãy bắt đầu từ 1
1 2 3 4 5 6 7 |
<span class="hljs-keyword">const</span> ( Running State = <span class="hljs-constant">iota</span> +<span class="hljs-number"> 1</span> Stopped Rebooting Terminated ) |
Hoặc có thể làm một cách khác
1 2 3 4 5 6 7 8 |
<span class="hljs-function"><span class="hljs-title">onst</span> <span class="hljs-params">( <span class="hljs-variable">Unknown</span> <span class="hljs-variable">State</span> = iota <span class="hljs-variable">Running</span> <span class="hljs-variable">Stopped</span> <span class="hljs-variable">Rebooting</span> <span class="hljs-variable">Terminated</span> )</span> </span> |
Hãy trả lại function ngay khi có thể
Nếu có xử lý
1 2 3 4 5 6 7 8 9 |
<span class="hljs-func"><span class="hljs-keyword">func</span> <span class="hljs-title">bar</span><span class="hljs-params">()</span> <span class="hljs-params">(string, error)</span> </span>{ v, err := foo() <span class="hljs-keyword">if</span> err != <span class="hljs-built_in">nil</span> { <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>, err } <span class="hljs-keyword">return</span> v, <span class="hljs-built_in">nil</span> } |
thì hãy thay bằng
1 2 3 4 |
<span class="hljs-function">func <span class="hljs-title">bar</span><span class="hljs-params">()</span> <span class="hljs-params">(<span class="hljs-keyword">string</span>, error)</span> </span>{ <span class="hljs-function"><span class="hljs-keyword">return</span> <span class="hljs-title">foo</span><span class="hljs-params">()</span> } </span> |
Sử dụng slices, map dưới dạng custom type
Giả sử chúng ta có một hàm trả về server list
1 2 3 4 5 6 7 8 9 10 11 12 13 |
type Server <span class="hljs-keyword">struct</span> { Name <span class="hljs-keyword">string</span> } <span class="hljs-function">func <span class="hljs-title">ListServers</span><span class="hljs-params">()</span> []Server </span>{ <span class="hljs-keyword">return</span> []Server{ {Name: <span class="hljs-string">"Server1"</span>}, {Name: <span class="hljs-string">"Server2"</span>}, {Name: <span class="hljs-string">"Foo1"</span>}, {Name: <span class="hljs-string">"Foo2"</span>}, } } |
Giả sử chúng ta muốn thêm việc filter tên Server vào thì sẽ phải sửa trực tiếp hàm ListServers, hoặc thêm hàm mới đại loại như ListServerFiltered, khá là phiền phức. Khi đó để xử lý đẹp đẽ, chúng ta chỉ cần gán type slice thành 1 type khác rồi bind xử lý mới vào nó
1 2 3 4 5 6 |
type Servers []<span class="hljs-function">Server <span class="hljs-title">func</span> <span class="hljs-params">(s Servers)</span> <span class="hljs-title">Filter</span><span class="hljs-params">(name <span class="hljs-keyword">string</span>)</span> Servers </span>{ <span class="hljs-comment">// trả về kết quả filter</span> } |
Sử dụng hàm wrappter WithContext
Giả sử chúng ta có rất nhiều xử lý giống nhau
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<span class="hljs-function">func <span class="hljs-title">foo</span><span class="hljs-params">()</span> </span>{ mu.Lock() defer mu.Unlock() <span class="hljs-comment">// foo</span> } <span class="hljs-function">func <span class="hljs-title">bar</span><span class="hljs-params">()</span> </span>{ mu.Lock() defer mu.Unlock() <span class="hljs-comment">// bar</span> } <span class="hljs-function">func <span class="hljs-title">qux</span><span class="hljs-params">()</span> </span>{ mu.Lock() defer mu.Unlock() <span class="hljs-comment">// qux</span> } |
Chúng ta có thể viết lại đẹp đẽ hơn
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 |
<span class="hljs-func"><span class="hljs-keyword">func</span> <span class="hljs-title">withLockContext</span><span class="hljs-params">(fn <span class="hljs-keyword">func</span>())</span> </span>{ mu.<span class="hljs-type">Lock</span> defer mu.<span class="hljs-type">Unlock</span>() fn() } <span class="hljs-func"><span class="hljs-keyword">func</span> <span class="hljs-title">foo</span><span class="hljs-params">()</span> </span>{ withLockContext(<span class="hljs-func"><span class="hljs-keyword">func</span><span class="hljs-params">()</span> </span>{ <span class="hljs-comment">// foo </span> }) } <span class="hljs-func"><span class="hljs-keyword">func</span> <span class="hljs-title">bar</span><span class="hljs-params">()</span> </span>{ withLockContext(<span class="hljs-func"><span class="hljs-keyword">func</span><span class="hljs-params">()</span> </span>{ <span class="hljs-comment">// bar </span> }) } <span class="hljs-func"><span class="hljs-keyword">func</span> <span class="hljs-title">qux</span><span class="hljs-params">()</span> </span>{ withLockContext(<span class="hljs-func"><span class="hljs-keyword">func</span><span class="hljs-params">()</span> </span>{ <span class="hljs-comment">// qux</span> }) } |
Kĩ thuật trên na ná kĩ thuật decorator của python
Sử dụng hàm getter, setter khi access map
Vì Map trong golang không phải là threadsafe, nên sử dụng getter, setter sẽ tốt hơn cho việc debug
1 2 3 4 5 |
<span class="hljs-keyword">type</span> Storage <span class="hljs-keyword">interface</span> { Delete(key <span class="hljs-typename">string</span>) Get(key <span class="hljs-typename">string</span>) <span class="hljs-typename">string</span> Put(key, value <span class="hljs-typename">string</span>) } |
Bài viết này thực hiện (hoặc lụm bài về đăng câu like từ các trang khác) bởi Việt Lâm Coder một YOUTUBER có tâm và đẹp trai siêu cấp vô địch zũ trụ.