ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、视频、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 接口值 接口的值,接口值,由两个部分组成,一个具体的类型和那个类型的值。它们被称为接口的动态类型和动态值。对于像Go语言这种静态类型的语言,类型是编译期的概念;因此一个类型不是一个值。在我们的概念模型中,一些提供每个类型信息的值被称为类型描述符,比如类型的名称和方法。在一个接口值中,类型部分代表与之相关类型的描述符。 ## 接口的动态类型和动态值 ~~~ var w io.Writer w = os.Stdout w.Write([]byte("hello")) w = new(bytes.Buffer) w.Write([]byte("hello")) w.String() //error,虽然动态类型是bytes.Buffer,但是因为接口的封装性,此时w没有String方法 buffer := w.(*bytes.Buffer) fmt.Println(buffer.String()) ~~~ ## 动态值大小 ~~~ var x interface{} = time.Now() ~~~ ![](https://img.kancloud.cn/bd/53/bd531f20be18d92ad2afb877b91a8856_672x312.png) 从概念上讲,不论接口值多大,动态值总是可以容下它。(这只是一个概念上的模型;具体的实现可能会非常不同) ## 警告,小心空指针非空接口 以下会引起panic ~~~ const debug = false func main() { var buf *bytes.Buffer if debug { buf = new(bytes.Buffer) } f(buf) } func f(out io.Writer) { //*bytes.Buffer对于io.writer来说是一个非空接口,所以下面!=的判断结果是false fmt.Println(out) //nil fmt.Println(out != nil) //false if out != nil { out.Write([]byte("done")) } } ~~~