golang 項目中坑


今天試着按照上一篇博客的設計自己實現自己的crawler,  踩了一路坑。有些找到了答案,有些沒有。我先將這些坑記錄下來,然后divide and conquer。

code snippet

 1 package util
 2 
 3 import (
 4     "math"
 5     "sync"
 6 )
 7 
 8 type IdGenerator interface {
 9     NextId() (uint64, error)
10 }
11 
12 type myIdGenerator struct {
13     rwmutex sync.RWMutex
14     seed    uint64
15 }
16 
17 func NewIdGenerator() (*IdGenerator, error) {
18     return new(myIdGenerator), nil
19 }
20 
21 //???RWMutex - two steps:  write after read.
22 func (this *myIdGenerator) NextId() (uint64, error) {
23     this.rwmutex.Lock()
24     defer this.rwmutex.Unlock()
25 
26     //read
27     if this.seed == math.MaxUint64 {
28         return 0, error.New("util.id.NextId(): id overflow")
29     }
30 
31     orig := seed
32 
33     //write
34     seed++
35     return orig, nil
36 }

 

 

坑一:struct -> interface

crawler\util\id.go:18: cannot use new(myIdGenerator) (type *myIdGenerator) as type *IdGenerator in return argument:
*IdGenerator is pointer to interface, not interface

 

solution: http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go

 

坑二:RWMutex read lock and write lock

本來計划,用讀鎖保護 seed 的讀取,之后用寫鎖保護seed 的修改。但是這個讀取和寫應該在一個transaction中,也就是說在自己讀取到seed 和寫seed之間,seed 不能被其他實體修改。

如果在讀鎖Lock時候,寫鎖重入(假定支持鎖升級重入),那么就會出現一種經典的死鎖現象。A, B 都申請到了讀鎖,現在A准備升級到寫鎖,A等待B釋放讀鎖,B也要升級而等待A釋放讀鎖。

本例中,資源鎖定的范圍並不大,一致用寫鎖對性能影響並不十分嚴重。但是如果讀寫臨界區都比較大,那么怎么解決呢?

 

坑三:interface 到底是 struct 還是 pointer? 這個應該與第一個坑屬於同一個問題的不同表象。

 1 package base
 2 
 3 import (
 4     "net/http"
 5 )
 6 
 7 type Response struct {
 8     resp  *http.Response
 9     depth uint
10 }
11 
12 ...
13 
14 func (this *Response) Valid() bool {
15     if this.resp != nil && this.resp.Body != nil {
16         return true
17     }
18 
19     return false
20 }

注意這行代碼,  

this.resp != nil && this.resp.Body

從定義中我們知道this.resp的類型是一個指針,所以其零值是一個指針。但是我們怎么知道 this.resp.Body表示什么,它是一個接口,其定義如下:

1 // Body represents the response body.
2     //
3     // The http Client and Transport guarantee that Body is always
4     // non-nil, even on responses without a body or responses with
5     // a zero-lengthed body.
6     //
7     // The Body is automatically dechunked if the server replied
8     // with a "chunked" Transfer-Encoding.
9     Body io.ReadCloser

是不是接口的實際類型都是指針,其零值都是nil?

如果接口可以表示struct, 那么編譯器如何判斷 obj == nil 類型是否匹配?難道編譯器知道interface 對應的真實類型, 用它的真實類型來判斷的嗎?

 

 

坑四   const in golang

 

golang 中的 const 比 c/c++中的 const 限定更加嚴格。

golang:   const a =  expr;    <----  golang 中右邊必須是 編譯期可以確定的常量。

而在 c\c++ 中,  const b = expr 右邊 可以是 運行期才能確定的值。

 

如果我要在程序中使用 一個運行期確定的值,同時想限制在后繼操作中不能修改此值,在 golang 中如何實現?貌似不能實現。-> 十分苦惱

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM