golang 项目中坑

今天试着按照上一篇博客的设计本身实现本身的crawler,  踩了一路坑。有些找到了答案,有些没有。我先将这些坑记录下来,而后divide and conquer。html

code snippetc++

 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 -> interfacegolang

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

 

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

 

坑二:RWMutex read lock and write lock性能

原本计划,用读锁保护 seed 的读取,以后用写锁保护seed 的修改。可是这个读取和写应该在一个transaction中,也就是说在本身读取到seed 和写seed之间,seed 不能被其余实体修改。ui

若是在读锁Lock时候,写锁重入(假定支持锁升级重入),那么就会出现一种经典的死锁现象。A, B 都申请到了读锁,如今A准备升级到写锁,A等待B释放读锁,B也要升级而等待A释放读锁。this

本例中,资源锁定的范围并不大,一致用写锁对性能影响并不十分严重。可是若是读写临界区都比较大,那么怎么解决呢?spa

 

坑三: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 中如何实现?貌似不能实现。-> 十分苦恼

相关文章
相关标签/搜索