你说Go里面有继承?我们拉黑吧!

2022-12-05 14:04:34 浏览数 (1)

很多从别语言转过来的同学,都会问,Go 里面有继承么?

那必须没有呀,不然怎么牛逼呀,哈哈。

Go 语言里面没有继承,如果谁给你说,Go 语言有继承你可以直接拉黑他了。

但是继承这个特性,真的很好用,很重要的一个特性,那 Go 语言是怎么处理这个特性的呢?

靠嵌套,只要我们嵌套了他,那我就拥有了他,从而间接实现了类似继承的特性。

一、嵌套结构体

咱举个例子,我们这个定义一个人类:

代码语言:javascript复制
type People struct {
 Name string //名字
}

然后我再定义一个学生:

代码语言:javascript复制
type Student struct {
 SId string //学号
}

目前这两个结构体没任何交集,实际上学生也是人类,所以他应该也有人类的属性。

所以如果其他语言里面 学生 就可以继承 人类。

Go 里面没继承,就直接嵌套,学生里面嵌套一个人类:

代码语言:javascript复制
type Student struct {
 People
 SId string //学号
}

这样我们在使用 Student 时也就有了人类的属性:

二、嵌套的一些特点

1、赋值

虽然我们可以直接通过点,取得对应的属性,但是在初始化时却不能。

你会发现找不到 Name 这个属性,我们只能结构体方式赋值:

大家多谢谢就熟练了哈。

如果你不是这种方式赋值,通过点的方式赋值,并不影响:

2、JSON

不仅赋值奇怪了点,转成 JSON 更奇怪。

我们现在给我们的结构体打上 Tag,然后转化成 JSON 字符串看看:

代码语言:javascript复制
type People struct {
 Name string `json:"name"` //名字
}

type Student struct {
 People
 SId string `json:"s_id"` //学号
}

func main() {
 stu := &Student{
  People: People{Name: "张三"},
  SId:    "N123",
 }
 fmt.Println(stu)
 b, _ := json.Marshal(stu)
 fmt.Println(string(b))
}

执行下看下结果:

代码语言:javascript复制
$ go run tt.go 
&{{张三} N123}
{"name":"张三","s_id":"N123"}

你会发现,如果直接打印结构体是能看到嵌套的,但是转成 JSON 时,却看不到嵌套的身影。

这个特性我们也可以反过来用!

代码语言:javascript复制
func main() {
 // 模拟用户提交的数据
 jsonStr := `{"name":"张三","s_id":"N123"}`
 stu := &Student{}
 json.Unmarshal([]byte(jsonStr), &stu)
 fmt.Println(stu)
}

执行下结果:

代码语言:javascript复制
$ go run tt.go 
&{{张三} N123}

你会发现,自动给嵌套的结构体赋值了。

3、方法

被嵌套的结构体方法,在嵌套的结构体上同样可以使用。

请看下面代码:

代码语言:javascript复制
type People struct {
 Name string `json:"name"` //名字
}

func (this *People) GetName() string {
 return this.Name
}

type Student struct {
 People
 SId string `json:"s_id"` //学号
}

func main() {
 stu := &Student{
  People: People{Name: "王五"},
  SId: "N34",
 }
 name := stu.GetName() //通过方法获取
 fmt.Println(name)
}

GetName 这个方法,在嵌套的 Student 上同样能调用。

于是我们可以衍生,是否能用这个属性去处理公共的接口呢?

感兴趣的同学可以去实操试试!

0 人点赞