什么是interface{}
简单的来说, interface{} 是指两个内容:
- 一堆方法 (a set of methods)
- 同时也是一个类型
对于Go中的interface{}, 通常指一个空的接口(empty interface), 也就是说这个interface并没有任何方法.
不像Java, 可以使用implement这种关键词来手动继承接口, 所以在Go中, 所有的类型(type), 即便一个不包含任何方法的类型(type), 都会自动的继承空的接口(也就是interface{}, 上一段中说的空的接口).
所以, 如果一个函数用interface{}作为参数, 那么意味着这个参数可以接受任何类型的值. 
困扰么?
假设我们有一个函数, 定义如下
func DoSomething(v interface{}) {
   // ...
}
那么在DoSomething的函数内部, v的类型是什么?  
v是任何类型 (vis of any type)
但这种观点显然是错误的, v并不是任何类型, 而是interface{}类型.
在调用DoSomething, 并且传递一个参数给DoSomething的时候, Go运行时会在必要的阶段执行一次类型转换(type conversion), 并且把这个传递的值转换为一个interface{}类型的值. 所以从运行时的角度看, 任何值都是一个类型的, 而且interface{}是v的一个静态类型(static type).
一个interface类型的值的结构是什么样的?
为了更进一步了解, 参考了一下Go Data Structures: Interfaces的部分内容
假设一个interface定义如下
type Stringer interface {
    String() string
}
Interface values are represented as a two-word pair giving a pointer to information about the type stored in the interface and a pointer to the associated data.
Assigning b to an interface value of type Stringer sets both words of the interface value.

interface类型的值通常包含两部分内容
- 一个指向该类型的方法表的指针
- 一个指向该类型的内容的指针
The first word in the interface value points at what I call an interface table or itable.
那么第一个word指向的是一个接口表itable(an interface table), 这段数据开头拥有一些关于需要的类的元信息(metadata), 之后便是一个储存各个方法的指针的列表.
Note that the itable corresponds to the interface type, not the dynamic type.
所以说itable只包含和interface{}类型有关的方法, 而不包含一个动态类型的所有方法.
换句话说, Stringer这个类型的itable虽然申明了需要Binary这个类, 但是itable的方法列表中却只有String这个方法, 而Binary类中的其他方法(比如Get)并没有出现在itable中.
The second word in the interface value points at the actual data.
interface结构中的第二个word是一个指向值的内存空间的指针, 也就是说Go运行时会开辟一段新的内存储存具体的值的内容. 所以当我们使用var s Stringer = b来申明s的时候, 其实是复制了b的内容, 而不是直接将指针指向b的内存地址. 所以当我们修改b的内容的时候, s的内容不会被改变.
通常情况下, 我们储存在interface中的值可能非常大, 但对于interface类型来说, 运行时只利用了1个word的大小来储存指针, 所以Go在堆中开辟了一大块内存, 并且用1个word大小的内存来记录这块内存的指针.