Go语言接口赋值实例介绍

本篇内容主要讲解“Go语言接口赋值实例介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Go语言接口赋值实例介绍”吧!

成都创新互联专注于扎囊网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供扎囊营销型网站建设,扎囊网站制作、扎囊网页设计、扎囊网站官网定制、微信平台小程序开发服务,打造扎囊网络公司原创品牌,更为您提供扎囊网站排名全网营销落地服务。

将对象实例赋值给接口

先看看将指定类型的对象实例赋值给接口,这要求该对象对应的类实现了接口要求的所有方法,这个是自然,否则也就不能算作实现该接口了,例如之前我们定义过一个Integer类型

type Integer int func (a Integer) Equal(i Integer) bool { return a == i} func (a Integer) LessThan(i Integer) bool { return a < i} func (a Integer) MoreThan(i Integer) bool { return a > i} func (a *Integer) Increase(i Integer) { *a = *a + i} func (a *Integer) Decrease(i Integer) { *a = *a - i}

相应地,我们定义一个接口IntNumber:

type IntNumber interface { Equal(i Integer) bool LessThan(i Integer) bool MoreThan(i Integer) bool Increase(i Integer) Decrease(i Integer)}

安装 Go 语言的约定,Integer类型实现了IntNumber接口。然后我们可以这样将Integer类型对应的对象实例赋值给IntNumber接口:

var a Integer = 1var b IntNumber = &a

注意到上述赋值语句中,我们将对象实例a的指针应用赋值给了接口变量,为什么要这么做呢?因为 Go 语言会根据类似下面这样的非指针成员方法:

func (a Integer) Equal(i Integer) bool

自动生成一个新的与之对应的指针成员方法:

func (a *Integer) Equal(i Integer) bool { return (*a).Equal(i)}

这样一来,类型*Integer就存在所有IntNumber接口中声明的方法,而Integer类型不包含指针方法Increase和Decrease(关于这一点我们前面已经介绍过),所以严格来说,只有*Integer类型实现了IntNumber接口。如果我们贸然将a的值引用赋值给b,编译时会报错:

cannot use a (type Integer) as type IntNumber in assignment: Integer does not implement IntNumber (Decrease method has pointer receiver)

显然,如果Integer类中实现的方法不是指针方法,则进行接口赋值时,传递对象实例的值引用给接口变量即可,否则需要传递指针变量。为了验证这一点,我们可以再创建一个新的接口IntNumber2:

type IntNumber2 interface { Equal(i Integer) bool LessThan(i Integer) bool MoreThan(i Integer) bool}

然后将对象实例a的值引用赋值给IntNumber接口变量:

var a Integer = 1varb1IntNumber=&avar b2 IntNumber2 = a

则上面两条接口赋值语句都可以编译通过。

将接口赋值给接口

接下来我们来看将一个接口赋值给另一个接口:在 Go 语言中,只要两个接口拥有相同的方法列表(与顺序无关),那么它们就是等同的,可以相互赋值。

下面我们来编写对应的示例代码,这是第一个接口Number1,位于oop1包中:

package oop1 type Number1 interface { Equal(i int) bool LessThan(i int) bool MoreThan(i int) bool}

这是第二个接口Number2,位于oop2包中:

package oop2 type Number2 interface { Equal(i int) bool MoreThan(i int) bool LessThan(i int) bool}

这里我们定义了两个接口,一个叫oop1.Number1,一个叫oop2.Number2,两者都定义五个相同的方法,只是顺序不同而已。在 Go 语言中,这两个接口实际上并无区别,因为:

任何实现了oop1.Number1接口的类,也实现了oop2.Number2;任何实现了oop1.Number1接口的对象实例都可以赋值给oop2.Number2,反之亦然;在任何地方使用oop1.Number1接口与使用oop2.Number2并无差异。

接下来我们定义一个实现了这两个接口的类Number:

type Number int; func (n Number) Equal(i int) bool { return int(n) == i;} func (n Number) LessThan(i int) bool { return int(n) < i;} func (n Number) MoreThan(i int) bool { return int(n) > i;}

所以下面这些赋值代码都是合法的,会编译通过:

var num1 Number = 1;var num2 oop1.Number1 = num1var num3 oop2.Number2 = num2

此外,接口赋值并不要求两个接口完全等价(方法完全相同)。如果接口 A 的方法列表是接口 B 的方法列表的子集,那么接口 B 可以赋值给接口 A。例如,假设Number2接口定义如下:

type Number2 interface { Equal(i int) bool MoreThan(i int) bool LessThan(i int) bool Add(i int)}

要让Number类继续保持实现这两个接口,需要在Number类定义中新增一个Add方法实现:

func (n *Number) Add(i int) { *n = *n + Number(i);}

接下来,将上面的接口赋值语句改写如下即可:

var num1 oop1.Number = 1;var num2 oop2.Number2 = &num1;var num3 oop1.Number1 = num2;

但是反过来不行:

var num1 oop1.Number = 1;var num2 oop1.Number1 = &num1;var num3 oop2.Number2 = num2; // 这一段编译出错

因为Number1接口中没有Add方法,这一点和 PHP/Java 中子类实例可以直接赋值给父类,而父类实例不能直接赋值给子类颇有些异曲同工。

到此,相信大家对“Go语言接口赋值实例介绍”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!


网站标题:Go语言接口赋值实例介绍
本文URL:http://azwzsj.com/article/iipcop.html