GO 接口详解

在go语言中,接口就是一种类型。同map、struct等的定义,语法是一样的。

如:

type People interface {
	Speak(string) string
}

关键字是interface。此时就称People是一个接口。接口内只有方法声明,没有方法的实现,也没有数据字段。

接口的作用就是定义一些对象的共同特征,特征以接口内的方法来定义。如上例的speak方法。

具有上述特征的类型,那就称它实现了这个接口。语法如下:

// 定义类型Student,它是一种struct类型 
type Student struct{}

// 类型Student实现People特征 (也就是让它实现People中的方法)
func (stu Student) Speak(think string) (talk string)  {
	if think == "hello world" {
		talk = "你好,世界"
	} else {
		talk = "您好"
	}
	return
}

实现好之后,Student对象就可以赋值给People类型变量了

var peo People = Student{}
think := "hello"
fmt.Println(peo.Speak(think))

上面代码输出:您好。

除了值类型能实现接口,指针类型也能实现接口,所谓指针类型实现是指如上面的speak实现,接收者改成指针声明。如下:

type Doctor struct{}

func (stu *Doctor) Speak(think string) (talk string) {
	if think == "check" {
		talk = "检查"
	} else {
		talk = "治疗"
	}
	return
}

同一种类型不能有两个同名的方法实现,指针和值接收者也算同一种类型,如上面有student值接收者实现了speak,不能再有student指针接收者实现speak。

值接收者实现和指针接收者实现的区别:

func main()  {
	var peo People = Student{}
	think := "hello"
	fmt.Println(peo.Speak(think))
	var peo2 People = &Student{}
	fmt.Println(peo2.Speak("hello world"))
	//var peo3 People = Doctor{}
	//fmt.Println(peo3.Speak("money"))
	var peo4 People = &Doctor{}
	fmt.Println(peo4.Speak("check"))
}

 注意,Doctor{}不能赋值给People类型的变量,会报错:cannot use Doctor{} (type Doctor) as type People in assignment:Doctor does not implement People (Speak method has pointer receiver)。意思就是Doctor对象并没有实现People接口。也就是说:值接收者实现接口时,对象和其指针都能赋值给相应的接口类型,而指针接收者实现的对象只能把其指针赋值给相应的接口类型
一个类型可以实现多个接口,比如学生还能实现孩子接口,拥有学习的特征

type Children interface {
	Study(string) string
}
func (stu Student) Study(book string) (obtain string)  {
	if book == "math" {
		obtain = "计算"
	} else {
		obtain = "其他"
	}
	return
}

func main(){ 
	var peo2 People = &Student{}
	fmt.Println(peo2.Speak("hello world"))
	var peo5 Children = Student{}
	fmt.Println(peo5.Study("math"))
}

接口嵌套

定义个接口的时候可以嵌套别的接口,这样就会拥有该接口的特征。

type Boy interface {
	People
	Children
}


func main(){
    var xiaoming Boy = Student{}
    fmt.Println(xiaoming.Speak("hello world"))
    fmt.Println(xiaoming.Study("english"))
}

如上面例子中的Boy。它嵌套了两个接口,拥有了这两个接口的特征Speak和Study。而Student类型有实现这两个特征,也就相当于实现了Boy接口,所以Student对象可以赋值给Boy类型的变量。

空接口 

空接口就是没有特征的接口类型,也就是没有定义任何方法。

type Empty interface {}

所以说在Go中,任何类型都实现了空接口。也就是指任何类型的变量都可以赋值给空接口类型的变量。那应该如何判断当前空接口所接收的类型呢。可以用x.(T)方法或者x.(type)。x为空接口类型变量。用法如下:

func justifyType(x interface{}) {
	switch v := x.(type) {
	case string:
		fmt.Printf("x is a string,value is %v\n", v)
	case int:
		fmt.Printf("x is a int is %v\n", v)
	case bool:
		fmt.Printf("x is a bool is %v\n", v)
	default:
		fmt.Println("unsupport type!")
	}

	v, ok := x.(string)
	if ok {
		fmt.Printf("I am string. value is %v type is %T\n", v, v)
	} else {
		fmt.Printf("I am not string. value is %v type is %T\n",v, v)
	}
}

func main(){  
	var a int = 88
	var b string = "hello"
	justifyType(a)
	justifyType(b)
}

x.(T): T是某种类型,比如x.(string),它会返回两个值,后一个值表示当前类型是不是string的布尔值,如果为true,则前一个值表示解析出来的值,类型也相应转为string,否则为空。

x.(type): 返回当前的类型,比如string。只能在switch中使用,否则编译不过。

上面例子会输出:

x is a int is 88
I am not string. value is  type is string
x is a string,value is hello
I am string. value is hello type is string
 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值