前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从测试中分析Go语言中的"继承"

从测试中分析Go语言中的"继承"

原创
作者头像
言志志
发布2023-10-13 22:56:08
2691
发布2023-10-13 22:56:08
举报
文章被收录于专栏:Go语言学习笔记Go语言学习笔记

前言

本文是探讨的是"go语言中的“继承”"

此文章是个人学习归纳的心得, 为掘金首发 , 如有不对, 还望指正, 感谢!

判断是否有阅读本文的必要,可以先看下面的样例

样例一

代码语言:go
复制
package main

type student struct {
     name string
     id   int
     age  int
}

func (s student) getName() string {
     return s.name
}


type schoolOne struct {
     student
}

type schoolTow struct {
     s student
}

请问schoolOne和schoolTow有什么区别? 在调用getName方法上,有什么区别?

答案

schoolOne和schoolTow都是嵌入了结构体student,但是schoolOne是隐式嵌入,schoolTow是显示嵌入,给这个结构体重命名为s,

隐式嵌入会实现go的自动转发,类似于其他语言的继承,就是说schoolOne得到了student的getName方法。

go语言作为一门极简的语言,是没有类一说的,但是go通过结构体和转发实现了类似类和继承的效果。

在调用上的区别:

代码语言:txt
复制
func main() {
   One := &schoolOne{struct {
      name string
      id   int
      age  int
   }{name: "言志志", id: 666, age: 18}}

   Tow := &schoolTow{struct {
      name string
      id   int
      age  int
   }{name: "言志志2", id: 999, age: 18}}

   fmt.Printf("%v", One.getName())
   fmt.Printf("%v", Tow.s.getName())
   fmt.Printf("%v", One.student6.getName())  //还可以这样
}

其实就是说,如果是隐式的话,就会比较方便,因为你没有给定字段名,显式的话,要通过字段名来调用。

代码语言:txt
复制
fmt.Printf("%v", Tow.student6.getName())  会报错

报错是因为,你已经给了字段名了,这个隐式的转发,也就是go的自动转发。

关于字段的自动转发的测试

属性也会自动转发

代码语言:txt
复制
package main

import "fmt"

type student struct {
   name string
   id   int
   age  int
}

func (s student) getName() string {
   return s.name
}

type schoolOne struct {
   student
}
func main() {
   One := &schoolOne{struct {
      name string
      id   int
      age  int
   }{name: "言志志", id: 666, age: 18}}

   fmt.Printf("%v", One.id)
}

运行结果:

但是需要注意的,这个字段的首字母,我用的小写,所以只能在包内可以这样,其他包引用的话,即使是转发了,但是由于没有公开,你还是看不到效果的

父结构体和嵌入的子结构体重名

代码语言:txt
复制
package main

import "fmt"

type student struct {
   name string
   id   int
   age  int
}

func (s student) getName() string {
   return s.name
}

type schoolOne struct {
   name string
   student
}

func (s schoolOne) getName() string {
   return s.name
}

func main() {
   One := &schoolOne{"言志志1号", struct {
      name string
      id   int
      age  int
   }{name: "言志志2号", id: 666, age: 18}}

   fmt.Printf("One.name:%v \n", One.name)
   fmt.Printf("One.student6.name: %v \n", One.student6.name)

   fmt.Printf("One.getName(): %v \n", One.getName())
   fmt.Printf("One.student6.getName(): %v \n", One.student6.getName())
}

运行结果如下:

就是如果重名的话,会先考虑父结构体里面的,要调用子结构体里面的,就是要用结构体名来调用

但是没有重名的就仍然会继承到那个父结构体上面,还是可以像之前一样调用。

我正在参与2023腾讯技术创作特训营第二期有奖征文,瓜分万元奖池和键盘手表

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 样例一
  • 答案
  • 关于字段的自动转发的测试
    • 属性也会自动转发
      • 父结构体和嵌入的子结构体重名
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档