# 接口
    接口类型是对其他类型行为的概括和抽象，通过使用接口我们可以写出更加灵活和通用的函数
    这些函数不用绑定在一个特定的类型实现上
    
    对于一个具体类型 无须声明他实现了哪些接口，只要提供接口所必需的方法即可

# 接口即约定
    之前介绍的类型都是具体类型， 具体类型指定了他所含的数据的精确布局
    还暴露了基于这个精确布局的内部操作，比如对于数值有算术造作
    对于slice类型有索引append range等
    具体类型还会通过其他方法来提供额外的能力
    总之你知道了一个具体类型的数据 你就精确的知道了他是什么以及他能干什么
    
    Go中还有另外一种类型称为接口类型， 他是一种抽象类型， 并没有暴露所含的数据的布局或者内部结构， 当然也没有那些数据的基本操作
    他所提供仅仅是一些方法而已。如果你拿到一个接口类型的值 你无从知道他是什么 仅仅知道他能做什么或者更精确的讲仅仅是他提供哪些方法
    
# 接口类型
    一个接口类型定义一套方法
    如果一个具体类型要实现该接口
    那么必须实现接口类型定义的所有方法
    接口还可以通过组合得到新的接口
    另外接口类型中方法的定义的顺序是无意义的，真正有意义的只有接口的方法集合
    
# 实现接口
    如果一个类型实现了一个接口要求的所有方法， 那么这个类型实现了这个接口
    通常所说的 具体类型是一个特定的接类型 这就代表这改具体类型实现了改接口
    
# 接口赋值规则
    仅当一个表达式实现了一个接口时 这个表达式才可以赋值给该接口
            
# 空接口类型 interface{}
    可以把任何值赋给控接口类型
    这样函数就能接受任意类型的参数了啦啦啦啦啦啦
    当然我们创建一个执行布尔值 浮点数 字符串 map 指针或其他类型的interface{}接口 也无法直接使用其中的值
    毕竟这个接口不包含任何方法 我们需要一个方法从空接口中还原出实际值  
    判断是否实现接口只需要毕竟具体类型和接口类型的方法 所以没必要在具体类型的定义中声明这种关系
 
# 接口值
    从概念上讲 一个接口类型的值简称接口值 其实有两个部分 一个具体类型和该类型的一个值 二者称为接口的动态类型和动态值
    接口的零值就是把它的动态类型和值都设置为nil  可以用 ==nil 或者 ！= nil来检测一个接口值是否为nil 
    调用一个nil接口的任何方法都会导致崩溃
    一般来讲 在编译时 无法知道接口值的动态类型是什么， 所以通过接口来做调用必然需要使用动态分发
    编译器必须生成一段代码来从类型描述符拿到名为write的方法地址 在间接调用该方法地址 调用这接收就是接口值的动态值
    
    一个接口值可以指向任意大的动态值 
    接口值是可以比较的 所以他可以作为map的key 也可以作为switch的语句操作数（仅仅能确认接口值包含动态值可以比较时 才能比较接口值 不然会崩溃）
    
    P158
    
    
    
    
    
    
    
    
              
    
     
    