今日概述
今天主要学习go的接口
1. 结构体匿名字段
- 匿名字段既然省略了,默认和类型名相同(可以理解为派生出来的)
- 匿名字段是结构体时,此时发生提升:
- 字段提升(另外一个结构体,在当前结构体可直接调用)
- 方法提升(另外结构体方法,可在当前结构体直接调用)
PS: 如果遇到字段名称一样的有歧义,通过匿名字段中间层区分
看代码:
package main
import "fmt"
type Person struct {
name string
age int
}
func (p *Person) hello() {
fmt.Println("hello")
}
type Student struct {
id string
Person // 匿名字段 相当于此时字段名也是Person
}
func main() {
p := Student{
id: "001",
Person: Person{name: "John", age: 12}, // 写时直接把字段写上
}
fmt.Println(p.id)
fmt.Println(p.name) // 字段提升
fmt.Println(p.age) // 字段提升
p.hello() // 方法提升
}
2. 匿名字段 (是指针)
用法和上述一样,唯一需要记住的在于,初始化结构体时要传指针;
看代码:
package main
import "fmt"
type Person struct {
name string
age int
}
func (p *Person) hello() {
fmt.Println("hello")
}
type Student struct {
id string
*Person // 初始化时候 要传指针
}
func main() {
p := Student{
id: "001",
Person: &Person{name: "John", age: 12}, // 初始化时候传指针
}
p.hello() // 方法提升
}
3. 什么是接口,有什么用?
概念:
接口相当于把不同的对象归类,具有同一类行为的我们称为同一个接口;比如,猪会叫、狗也会叫,鸭子也会叫,那么我们可以把叫这个行为动作抽象为一类接口;
有什么用?
go做为静态语言,它是强类型的;我们赋值给变量,这个变量都需要有一个类型,比如我们有一个猫 struct 还有一个 狗 struct 他们都实现了叫方法;我们定义变量时候需要给猫和狗定义不同的类型,才能赋值;
其实很麻烦,实现了接口后,我们可以不用区分猫还是狗,直接赋值给这个接口类型就行。
4. 接口中方法的接收者(值/指针)区别
- 值(随便调用) — 值/指针赋给接口类型都可
- 指针(严格) — 只能指针
一点小建议,
- 严格按照接收者去生成对象是个好习惯
- 在同一个结构体下方法,统一生成,要么是值接收者/要么是方法接收者
看代码
package main
import "fmt"
type Mover interface {
move()
}
type Dog struct{}
// 值接收者 - 在接口中宽松
func (d Dog) move() {
fmt.Println("dog move")
}
type Cat struct{}
// 指针接收者 - 严格
func (c *Cat) move() {
fmt.Println("cat move")
}
func main() {
var x Mover // 接口是一种类型
// 值接收者 (啥都行)
x = Dog{}
x.move()
x = &Cat{}
x.move()
// 指针接收者 严格
x = &Cat{}
x.move()
// 不能这么用
// x = Cat{} cannot use Cat{} (value of type Cat) as Mover value in assignment: Cat does not implement Mover (method move has pointer receiver)
// x.move()
}
5. 接口嵌套
多个接口,可以组合生成一个新的接口;非常不错哦。
package main
import "fmt"
type Mover interface {
move()
}
type Sayer interface {
say()
}
type Animaler interface {
Mover // 接口
Sayer // 接口 此时合并了上述两个接口
}
// dog实现了Animaler接口
type Dog struct{}
func (d *Dog) move() {
fmt.Println("dog move")
}
func (d *Dog) say() {
fmt.Println("dog say")
}
func main() {
var x Animaler = &Dog{} // 合并成一行写也不错哦
x.say()
x.move()
}
网友评论