golang中的陷阱

写过其他后端语言的人,在写golang的时候,总会遇到一些奇怪的问题,而且很难排查,我个人觉得是因为两个原因,第一个golang基础不扎实,第二个编程思维没有转换过来。下面都是我自己遇到或者想到的容易遇到的点。如果转载的话,请注明出处,因为我会不定期更新。

1、到底是什么类型

这是我自己想的问题,看以下代码,T到底是什么类型?

type A interface{
    Do() error
}
type B interface{
    Do() error
}

type T int
func (t T)Do() error{
    return nil
}

曾经在某个golang群里问过这个问题,当时没有人回答这个问题,也许是太简单了,不屑,或者是不确定。
请认真思考。
下面是我的分析
T到底什么类型?首先万物皆interface,其次,看T的定义,是int的别名,也就是int32的别名,最后,T实现了Do()方法,但是,A 和 B都申明了这个方法,那么,T到底是A类型呢,还是B类型?答案是T既是
A也是B。为什么?因为golang中,只要实现了某个接口的所有方法,那么它就是这种类型。另一个佐证是goland中的实现关系:


Screenshot from 2018-05-24 11-23-52.png
Screenshot from 2018-05-24 11-25-13.png

2、range迭代

代码如下,请先思考运行后的结果是什么:

type student struct {
    Name string
    Age int
}

func main (){
    m := make(map[string]*student)
    stus := []student{
        {Name: "zhou", Age: 24},
        {Name: "li", Age: 23},
        {Name: "wang", Age: 22},
    }
    for _, stu := range stus {
        m[stu.Name] = &stu
    }
    for _,stu := range stus{
        fmt.Println(m[stu.Name])
    }
}

是不是觉得应该是:

&{zhou 24}
&{li 23}
&{wang 22}

但,运行之后的结果为:

&{wang 22}
&{wang 22}
&{wang 22}

为什么?首先从短赋值说起

for _, stu := range stus {
    m[stu.Name] = &stu
}
等同与
var stu student
for _, stu = range stus {
    m[stu.Name] = &stu
}

是不是有点头绪了?因为每次m[stu.Name] = &stu 执行的时候,指向都是stu,而每次迭代,stu指向不同的student,最终的结果就是,所有的数据都指向了最后一个student。至于stu.Name 是不用怀疑的,每次迭代都是立即求值。

那么如何解决呢?既然问题是由于stu引起的,那么,每次迭代让指针指向迭代对象就可以解决,引入新变量就可以:

for _, stu := range stus {
        st := stu
    m[st.Name] = &st
}

或者,map的值不存指针,存对象即可:

m := make(map[string]*student)
...
for _, stu := range stus {
    m[stu.Name] = stu
}
...

3、申明类型

这个是我写工具类的时候遇到的,不多说,直接上代码:

var buf bytes.Buffer
...//write data to buf
r, err := http.NewRequest("PUT", uri+"/apis/", buf)

你会发现,最后一行会报错的,看下NewRequest的定义,最后一个参数是io.Reader类型:

func NewRequest(method, url string, body io.Reader) (*Request, error)

func (b *Buffer) Read(p []byte) (n int, err error) 

很明显,bytes.Buffer 实现了io.Reader接口,根据第一个问题得出的结论,Buffer就是io.Reader类型啊,为什么会报错呢?当然,也不能申明buf为io.Reader对吧,因为我们要往buf里面写入数据呢。
当然用Buffer是没错啦,问题在于我们显式申明buf 为bytes.Buffer,那么类型就已经定了,注定不能用在io.Reader参数上了,虽然它确实是实现了io.Reader 的接口。
原因找到了,怎么解决呢?我们可以不用申明buf是Buffer类型:

buf  := new(bytes.Buffer)
...//write data to buf
r, err := http.NewRequest("PUT", uri+"/apis/", buf)

这样就OK了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,531评论 18 399
  • 第一章 Nginx简介 Nginx是什么 没有听过Nginx?那么一定听过它的“同行”Apache吧!Ngi...
    JokerW阅读 32,624评论 24 1,002
  • 青春是我们奔跑的背影;青春是我们在操场上挥洒汗水;青春是无数次失败后的努力;青春是成功的喜悦…… ...
    伟xcw阅读 337评论 1 0
  • 看曾经的梦想,在别人身上一一实现;看理想的样子,在别人身上一一出现;看期待的事情,在别人身上一一做到。然后...
    惯看烟雨一意行阅读 194评论 0 0
  • 今天是我和爱梅一起举办的第一期分享会,很开心邀约来的朋友基本都如期而至,感恩一切最美好的安排,今天的分享会圆满成功...
    Amy心灵之屋阅读 153评论 0 0