一、继承
可以通过在一个结构体中嵌入另一个结构体的方式,

假设我们有一个名为 Animal 的结构体:

type Animal struct {
    name string
}

func (a *Animal) Move() {
    fmt.Printf("%s is moving\n", a.name)
}

然后我们可以通过嵌入 Animal 结构体来定义一个新的结构体 Dog:

type Dog struct {
    *Animal // 嵌入 Animal 结构体
}

func main() {
    dog := &Dog{&Animal{"doggy"}}
    dog.Move() // 调用 Animal 结构体中的 Move 方法
}

*Animal
全限定名
二、接口

2.1 接口定义

接口(interface)合约类型(contract type)

2.2 接口实现

一个类型如果拥有一个接口需要的所有方法,那么这个类型就实现了这个接口

假设我们定义一个Usb的接口,手机和电脑都可以插入,并提供了一个Start方法

type Usb interface {
	Start()
}

现在我们提供了小米和苹果手机去插入

type Phone struct {
}
type Xiaomi struct {
}

//phone结构体实现Usb的方法
func (p Phone)Start(){
fmt.Println("我的苹果手机插入了!!!")
}
func (p Phone)Stop(){
fmt.Println("我的苹果手机拔出了!!!")
}
// xiaomi结构体实现Usb的方法
func (x Xiaomi)Start(){
fmt.Println("我的小米手机插入了!!!")
}
func (x Xiaomi)Start(){
fmt.Println("我的小米手机插入了!!!")
}

上述两个结构体实现了Usb的所有方法,那么我们就可以说该结构体已经实现了Usb接口,现在我们进行调用。

func (c Computer) Working(usb ...Usb) {
	for _, u := range usb {
		u.Start()
		u.Stop()
	}
}

我们这块使用了多态的思想(一个方法在不同的类型中具有不同的行为),定义一个方法Working去处理

	c := Computer{}
	p := Phone{}
	x := Xiaomi{}
	//多态的体现
	c.Working(p,x)

2.3 接口注意事项

实现接口的类型必须实现接口中定义的所有方法。
三、类型断言

3.1 定义

将接口类型的值转换为其它类型的方法

3.2 类型断言的方式

  • 基于接口的类型断言
x.(T)
var i interface{} = "hello"

s := i.(string) // 正确,s 的值为 "hello"
n := i.(int) // 错误,将导致运行时错误

需要注意的是,在使用基于接口值的类型断言时,需要确保接口值不为 nil,否则将引发运行时错误。因此,可以使用 if 语句结合类型断言来检查接口值的类型,例如:

var i interface{} = "hello"

if s, ok := i.(string); ok {
    fmt.Println("i is a string:", s)
} else {
    fmt.Println("i is not a string")
}