我在学习Go语言的时候,感觉方法,接口这块书上都写的很玄乎,不是很好理解,搞得一头雾水,以下是我个人的一些粗浅理解,希望有问题的地方大家能够及时指出。
方法
方法其实就是某些类型特定的函数,即方法和struct
绑定,绑定这个这个方法(特殊的函数
)也就变成了struct
的一个属性,可以直接调用,例如:
package main
import (
"fmt"
)
type Person struct{
Name string
Age int
}
func (p *Person) Info() string {
return p.Name
}
func main(){
man := Person{
"superman",
20000,
}
fmt.Println(man.Name,"\n",man.Info())
}
##输出:
superman
superman
接口
接口是双方约定的一种合作协议。接口实现者不需要关心接口会被怎样使用,调用者也不需要关心接口的实现细节。接口是一种类型,也是一种抽象结构,不会暴露所含数据的格式、类型及结构。接口由方法组成。
引入一个名词,函数签名:即一个函数的信息,包括函数名,参数类型,参数个数,顺序
假设一个方法[特殊的函数
]是Info(),只要函数签名一致的情况下,即使绑定了不同的struct
,也就是不同的receiver
的情况下,可以放到同一个接口下,同时,接口也是一种类型struct
,接口作为一种struct
,它是可以被赋予任何类型的数据实例的。
举个栗子:
package main
import (
"fmt"
)
//接口包含了两个方法
type Pet interface{
Action() string
Info()
}
//结构体1
type Cat struct{
Name string
Age int
}
//结构体2
type Dog struct{
Name string
Age int
}
//绑定Cat的方法1
func (c *Cat) Action() string{
return "喵喵喵"
}
//绑定Cat的方法2
func (c *Cat) Info(){
fmt.Println("I am a cat")
}
//绑定Dog的方法1
func (d *Dog) Action() string{
return "汪汪汪"
}
//绑定Dog的方法2
func (d *Dog) Info() {
fmt.Println("I am a dog")
}
func main(){
c := Cat{
"mimi",
2,
}
d := Dog{
"tuowazi",
2,
}
var pet Pet
//pet是interface类型,可以被赋予任何类型,这边c是struct,赋予之后,就拥有Cat结构体所绑定的方法,方法作为属性可以直接调用
pet = &c
fmt.Println(pet.Action())
pet.Info()
pet = &d
fmt.Println(pet.Action())
pet.Info()
}
##输出:
喵喵喵
I am a cat
汪汪汪
I am a dog
这里需要注意的是:如果接口里方法绑定的是指针类型变量,接口赋值时一定加上取址符。另外接口中的方法需要全部实现才可以编译通过。
struct,方法,接口之间的关系
方法本身也是函数,函数签名一样的情况下,这边认为是同样的方法。相同的方法可以有不同的receiver(绑定不同的struct
),另外同一个接口下可以有不同的方法,同一个方法也可以放在不同的接口中,总结一下就是:struct和接口之间可以是多对多,它俩之间的关系是通过方法衔接的,只要有相应的方法,就可以直接引用,无须关注具体的关联方式。接口可以想象成一个逻辑概念,假设一个接口interface1
封装的是鸟的特性(比如会飞,会叫),这个接口下面有飞的函数,叫的函数,这时你只要绑定不同的type(老鹰,麻雀,甚至是鸭等等),Go其实就是通过这种方式实现了多态,即interface1既可以实现老鹰,也可以实现麻雀,甚至鸡,鸭都可以。