🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] 参考链接:[https://juejin.im/post/5ad1c766518825555e5e4646](https://juejin.im/post/5ad1c766518825555e5e4646) ## interface{}之对象转型坑 一个语言用的久了,难免使用者的思维会受到这个语言的影响,interface{}作为Go的重要特性之一,它代表的是一个类似`*void`的指针,可以指向不同类型的数据。所以我们可以使用它来指向任何数据,这会带来类似与动态语言的便利性,如以下的例子: ``` type BaseQuestion struct{ QuestionId int QuestionContent string } type ChoiceQuestion struct{ BaseQuestion Options []string } type BlankQuestion struct{ BaseQuestion Blank string } func fetchQuestion(id int) (interface{} , bool) { data1 ,ok1 := fetchFromChoiceTable(id) // 根据ID到选择题表中找题目,返回(ChoiceQuestion) data2 ,ok2 := fetchFromBlankTable(id) // 根据ID到填空题表中找题目,返回(BlankQuestion) if ok1 { return data1,ok1 } if ok2 { return data2,ok2 } return nil ,false } ``` 在上面的代码中,data1是`ChoiceQuestion`类型,data2是`BlankQuestion`类型。因此,我们的interface{}指代了三种类型,分别是`ChoiceQuestion`、`BlankQuestion`和`nil`,这里就体现了Go和面向对象语言的不同点了,在面向对象语言中,我们本可以这么写: ``` func fetchQuestion(id int) (BaseQuestion , bool) { ... } ``` 只需要返回基类`BaseQuestion`即可,需要使用子类的方法或者字段只需要向下转型。然而在Go中,并没有这种`is-A`的概念,代码会无情的提示你,返回值类型不匹配。 ## interface{}之`nil`坑 ``` Under the covers, interfaces are implemented as two elements, a type and a value. The value, called the interface's dynamic value, is an arbitrary concrete value and the type is that of the value. For the int value 3, an interface value contains, schematically, (int, 3). 在幕后,接口被实现为两个元素,一个类型和一个值。该值称为接口的动态值,是一个任意的具体值,类型是该值的类型。对于int值3,一个接口值按模式包含(int, 3)。 ``` 参考链接:[https://www.jianshu.com/p/a5bc8add7c6e](https://www.jianshu.com/p/a5bc8add7c6e) ## golang的struct里面嵌入interface