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)
}
执行结果如下
除了上述功能外,接口的另一个功能是向用户暴露接口中定义过的方法,而隐藏没有定义过的方法。
例如,在下面代码中,类型 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)
}
接口具体是接收指针变量还是普通变量,由结构体定义方法的方式确定
-- 结构体定义方法形式如下,则传递指针变量
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()
}
}
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进行相关的项目开发及研发工作。