1.7.1 接口的赋值

一、接口的赋值

  1. Go语言的接口不支持直接实例化,但支持赋值操作,从而快速实现接口与实现类的映射

  2. 接口赋值在Go语言中分为如下两种情况

    1. 将实现接口的对象实例赋值给接口

    2. 将一个接口赋值给另一个接口

二、将实现接口的对象实例赋值给接口

  1. 将实现接口的对象实例赋值给接口,该要求对象对应的实现了接口要求的所有方法,否则也不能算作实现该接口了

  2. 示例如下:

    1. 首先顶一个Number类型以及相关方法

      type Number int
      
      func (x Number) Equal(i Number) bool {
      	return x == i
      }
      
      func (x Number) LessThan(i Number) bool {
      	return x < i
      }
      
      func (x Number) MoreThan(i Number) bool {
      	return x > i
      }
      
      func (x *Number) Multiple(i Number) {
      	*x = *x * i
      }
      
      func (x *Number) Divide(i Number) {
      	*x = *x / i
      }
    2. 相应的,定义一个接口NumberI

      type NumberI interface {
      	
      	Equal(i Number) bool
      	LessThan(i Number) bool
      	MoreThan(i Number) bool
      	Multiple(i Number)
      	Divide(i Number)
      	
      }
    3. 按照Go语言的规定,Number类实现了NumberI接口,然后可以将Number类型对应的对象实例赋值给NumberI接口

      var x Number = 8
      var y NumberI = &x
    4. 在上面的赋值语句汇总中,将对象实例x的指针赋值给了接口变量,原因如下

      func (x Number) Equal(i Number) bool {
      	return x == i
      }
      func (x *Number) Equal(i Number) bool {
          return (*x).Equal(i)
      }
      1. Go语言会根据第一个方法的费指针成员方法,自动生成一个新的与之对应的成员方法

      2. 这样一来,类型*Number就存在所有NumberI接口中声明的方法了

三、将接口赋值给接口

  1. 在Go语言中,只要两个接口用友相同的方法列表(与顺序无关),那他们就是相等的,可以相互赋值

  2. 示例代码:

    1. 首先创建一个名为oop1的包,创建第一个接口NumberInterface1

    2. 然后创建一个名为oop2的包,创建第二个接口NumberInterface2

  3. 定义了上面的两个接口,都定义了三个相同而方法,只有顺序不同,在Go语言中,上岸两个接口并无实际区别,原因如下

    1. 任何实现了NumberInterface1接口的类,也实现了NumberInterface2

    2. 实现了NumberInterface1接口的对象实例都可以赋值给NumberInterface2,反之亦然

    3. 在任何地方使用NumberInterface1接口与使用NumberInterface2并无差异

  4. 接下来实现这两个接口的类Number

  5. 这时,赋值代码都是合法的,编译时能通过

  6. 此外,接口赋值并不要求两个接口完全等价(方法完全相同),如果A方法列表是B方法列表的子集,那么接口B可以赋值给接口A

  7. 如上面的示例中

    1. NumberInterface2添加了一个方法

    2. 实现方法中添加内容

    3. 那么,将语句改写成如下方式依旧可以正常运行

Last updated