Golang学习之接口的使用

摘要

Golang的接口在实际的开发当中具有重要的作用,掌握接口的使用可以在一定场景下实现一些特殊的功能。

正文

本文主要围绕以下几个方面来讲解Golang接口的使用。

什么是接口

在Golang中,接口是包含一类方法的数据结构,定义为

type name interface{
	method1(param_list) return_type
	method2(param_list) return_type
	....
	methodn(param_list) return_type
}

接口的作用是抽象化这些方法,即metho1,method2, ⋯ \cdots ,methodn是没有实体的函数名。这些方法具体的行为由具体结构体或变量确定。

  • 举例说明
package main

import (
	"fmt"
	"reflect"
)

type A struct{

}

func(a *A)handle(x,y int){
	fmt.Println(reflect.TypeOf(a),x+y)
}

type B struct{

}
func(b *B)handle(x,y int){
	fmt.Println(reflect.TypeOf(b),x*y)
}

type Face interface{
	handle(x,y int)
}

func main() {
	fmt.Println("******Type A*****")
	var a *A
	var c Face
	c=a;
	c.handle(1,2);
	fmt.Println("******Type B*****")
	var b *B
	c=b;
	c.handle(1,2)
}

执行结果如下
Golang学习之接口的使用_第1张图片
除了上述功能外,接口的另一个功能是向用户暴露接口中定义过的方法,而隐藏没有定义过的方法。
例如,在下面代码中,类型 A定义了两个方法,分别是handle和handle1,而接口类型Face仅仅抽象出了一个方法handle。那么,将结构体指针变量a赋值给c以后,通过变量c智能看到handle方法。具体测试代码如下:

package main

import (
	"fmt"
	"reflect"
)

type A struct{

}

func (a *A)handle(x,y int){
	fmt.Println(reflect.TypeOf(a),x+y)
}

func (a *A)handle1(){
	fmt.Println("Hello World!")
}

type Face interface{
	handle(x,y int)
}

func main() {
	fmt.Println("******Type A*****")
	var a *A
	var c Face
	c=a;
	c.handle(1,3)
}

具体情况如下
Golang学习之接口的使用_第2张图片

  • 接口使用的注意事项

接口具体是接收指针变量还是普通变量,由结构体定义方法的方式确定

-- 结构体定义方法形式如下,则传递指针变量
func (a *A) method(paralist) return_type{
	.....
	return return_type
}
-- 结构体定义方法形式如下,则传递普通变量
func (a A) method(paralist) return_type{
	.....
	return return_type
}

接口中的方法全包含在接口体定义的方法中

接口作为函数的形参

  • 输入参数
    作为函数的输入参数,用于选择满足条件的实参。
package main

import (
	"fmt"
	"reflect"
)

type A struct{

}

func (a *A)handle(x,y int){
	fmt.Println(reflect.TypeOf(a),x+y)
}

func (a *A)handle1(){
	fmt.Println("Type:A")
}

type B struct{

}

func (b *B)handle(x,y int){
	fmt.Println(reflect.TypeOf(b),x*y)
}

func (b *B)handle1(){
	fmt.Println("Type:B")
}

type Face interface{
	handle(x,y int)
}

func main() {
	fmt.Println("******Type A*****")
	var a *A
	var c Face
	c=a;
	process(a)
	fmt.Println("******Type B*****")
	var b *B
	c=b;
	process(c)
}
func process(f Face) {
    // check the type of inputing argument
	switch t:=f.(type){
		case *A:
			t.handle1()
	case *B :
		t.handle1()
	}
}

上述实例的执行结果如下:
Golang学习之接口的使用_第3张图片

  • 输出参数
    限定输出满足指定接口的结果,具体如下
package main

import (
	"fmt"
	"reflect"
)

type A struct{
	X int
}

func (a *A)handle(x,y int){
	fmt.Println(reflect.TypeOf(a),x+y)
}

func (a *A)handle1(){
	fmt.Println("Type:A")
}

type Face interface{
	handle(x,y int)
}


func main() {
	var a A
	a.X=4
	b:=process(&a)
	c:=b.(*A)
	fmt.Printf("addr a=%p,addr b=%p, addr c=%p\n",&a,b,c)
	fmt.Println(c.X)
}

func process(f *A) Face{
	return f
}

实例执行结果为:
在这里插入图片描述

用结构体和接口实现类和类的继承

Golang没有像C++一样的类,在Golang中,继承的实现是依靠结构体来实现,为了限定子类只继承部分父类的方法,这里需要引入接口来实现。

  • 基本结构体
type A struct {
    varI Type1
    varII Type2
}

func(a *A) Method(paramlist) return_type{
	.....
	return return_type
}
  • 继承父类结构体指定方法
package main

import (
	"fmt"
	"reflect"
)

type A struct{
	X int
}

func (a *A)handle(x,y int){
	fmt.Println(reflect.TypeOf(a),x+y)
}

func (a *A)handle1(){
	fmt.Println("Type:A")
}

type Face interface{
	handle(x,y int)
}

type B struct{
	z Face
}


func main() {
	b:=Init()
	b.z.handle(1,2)
}

func Init() *B{
	a:=new(A)
	return &B{a}
}

此时,结构体B中将包含架构体A唯一的方法handle.

总结

Golang中,接口是非常关键的数据类型,只有掌握并使用号接口,才能更好地利用Golang进行相关的项目开发及研发工作。

你可能感兴趣的:(golang,开发语言,后端)