【Go入门】struct类型

【Go入门】struct类型

struct

Go语言中,也和C或者其他语言一样,我们可以声明新的类型,作为其它类型的属性或字段的容器。例如,我们可以创建一个自定义类型person代表一个人的实体。这个实体拥有属性:姓名和年龄。这样的类型我们称之struct。如下代码所示:


type person struct {name stringage int
}

看到了吗?声明一个struct如此简单,上面的类型包含有两个字段

  • 一个string类型的字段name,用来保存用户名称这个属性
  • 一个int类型的字段age,用来保存用户年龄这个属性

如何使用struct呢?请看下面的代码


type person struct {name stringage int
}var P person  // P现在就是person类型的变量了P.name = "Astaxie"  // 赋值"Astaxie"给P的name属性.
P.age = 25  // 赋值"25"给变量P的age属性
fmt.Printf("The person's name is %s", P.name)  // 访问P的name属性.

除了上面这种P的声明使用之外,还有另外几种声明使用方式:

  • 1.按照顺序提供初始化值

    P := person{“Tom”, 25}

  • 2.通过field:value的方式初始化,这样可以任意顺序

    P := person{age:24, name:“Tom”}

  • 3.当然也可以通过new函数分配一个指针,此处P的类型为*person

    P := new(person)

下面我们看一个完整的使用struct的例子


package mainimport "fmt"// 声明一个新的类型
type person struct {name stringage int
}// 比较两个人的年龄,返回年龄大的那个人,并且返回年龄差
// struct也是传值的
func Older(p1, p2 person) (person, int) {if p1.age>p2.age {  // 比较p1和p2这两个人的年龄return p1, p1.age-p2.age}return p2, p2.age-p1.age
}func main() {var tom person// 赋值初始化tom.name, tom.age = "Tom", 18// 两个字段都写清楚的初始化bob := person{age:25, name:"Bob"}// 按照struct定义顺序初始化值paul := person{"Paul", 43}tb_Older, tb_diff := Older(tom, bob)tp_Older, tp_diff := Older(tom, paul)bp_Older, bp_diff := Older(bob, paul)fmt.Printf("Of %s and %s, %s is older by %d years\n",tom.name, bob.name, tb_Older.name, tb_diff)fmt.Printf("Of %s and %s, %s is older by %d years\n",tom.name, paul.name, tp_Older.name, tp_diff)fmt.Printf("Of %s and %s, %s is older by %d years\n",bob.name, paul.name, bp_Older.name, bp_diff)
}

struct的匿名字段

我们上面介绍了如何定义一个struct,定义的时候是字段名与其类型一一对应,实际上Go支持只提供类型,而不写字段名的方式,也就是匿名字段,也称为嵌入字段。

当匿名字段是一个struct的时候,那么这个struct所拥有的全部字段都被隐式地引入了当前定义的这个struct。

让我们来看一个例子,让上面说的这些更具体化


package mainimport "fmt"type Human struct {name stringage intweight int
}type Student struct {Human  // 匿名字段,那么默认Student就包含了Human的所有字段speciality string
}func main() {// 我们初始化一个学生mark := Student{Human{"Mark", 25, 120}, "Computer Science"}// 我们访问相应的字段fmt.Println("His name is ", mark.name)fmt.Println("His age is ", mark.age)fmt.Println("His weight is ", mark.weight)fmt.Println("His speciality is ", mark.speciality)// 修改对应的备注信息mark.speciality = "AI"fmt.Println("Mark changed his speciality")fmt.Println("His speciality is ", mark.speciality)// 修改他的年龄信息fmt.Println("Mark become old")mark.age = 46fmt.Println("His age is", mark.age)// 修改他的体重信息fmt.Println("Mark is not an athlet anymore")mark.weight += 60fmt.Println("His weight is", mark.weight)
}

图例如下:

在这里插入图片描述

图2.7 struct组合,Student组合了Human struct和string基本类型

我们看到Student访问属性age和name的时候,就像访问自己所有用的字段一样,对,匿名字段就是这样,能够实现字段的继承。是不是很酷啊?还有比这个更酷的呢,那就是student还能访问Human这个字段作为字段名。请看下面的代码,是不是更酷了。


mark.Human = Human{"Marcus", 55, 220}
mark.Human.age -= 1

通过匿名访问和修改字段相当的有用,但是不仅仅是struct字段哦,所有的内置类型和自定义类型都是可以作为匿名字段的。请看下面的例子


package mainimport "fmt"type Skills []stringtype Human struct {name stringage intweight int
}type Student struct {Human  // 匿名字段,structSkills // 匿名字段,自定义的类型string sliceint    // 内置类型作为匿名字段speciality string
}func main() {// 初始化学生Janejane := Student{Human:Human{"Jane", 35, 100}, speciality:"Biology"}// 现在我们来访问相应的字段fmt.Println("Her name is ", jane.name)fmt.Println("Her age is ", jane.age)fmt.Println("Her weight is ", jane.weight)fmt.Println("Her speciality is ", jane.speciality)// 我们来修改他的skill技能字段jane.Skills = []string{"anatomy"}fmt.Println("Her skills are ", jane.Skills)fmt.Println("She acquired two new ones ")jane.Skills = append(jane.Skills, "physics", "golang")fmt.Println("Her skills now are ", jane.Skills)// 修改匿名内置类型字段jane.int = 3fmt.Println("Her preferred number is", jane.int)
}

从上面例子我们看出来struct不仅仅能够将struct作为匿名字段,自定义类型、内置类型都可以作为匿名字段,而且可以在相应的字段上面进行函数操作(如例子中的append)。

这里有一个问题:如果human里面有一个字段叫做phone,而student也有一个字段叫做phone,那么该怎么办呢?

Go里面很简单的解决了这个问题,最外层的优先访问,也就是当你通过student.phone访问的时候,是访问student里面的字段,而不是human里面的字段。

这样就允许我们去重载通过匿名字段继承的一些字段,当然如果我们想访问重载后对应匿名类型里面的字段,可以通过匿名字段名来访问。请看下面的例子


package mainimport "fmt"type Human struct {name stringage intphone string  // Human类型拥有的字段
}type Employee struct {Human  // 匿名字段Humanspeciality stringphone string  // 雇员的phone字段
}func main() {Bob := Employee{Human{"Bob", 34, "777-444-XXXX"}, "Designer", "333-222"}fmt.Println("Bob's work phone is:", Bob.phone)// 如果我们要访问Human的phone字段fmt.Println("Bob's personal phone is:", Bob.Human.phone)
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/169489.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python】KDtree的调用

前言 查询点集中与目标点最近的k个点 from scipy.spatial import cKDTree import numpy as npdata np.array([[1,2],[1,3],[4,5]]) # 生成 100 个三维数据 tree cKDTree(data) # 创建 K-D Tree result tree.query(np.array([5, 5]), k2) # 查询与 [0.5, 0.5, 0.5] 最近的三…

xsschallenge通关攻略详解

xsschallenge通过攻略 文章目录 xsschallenge通过攻略第一关第二关第三关第四关第五关第六关第七关第八关第九关第十关第十一关第十二关第十三关 简述 xsschallenge挑战攻略 ps: 终极测试代码 <sCr<ScRiPt>IPT>OonN"\/(hrHRefEF)</sCr</ScRiPt>IPT&g…

科技改变农业:合成数据农业中的应用

介绍 农业在我们的生活中起着至关重要的作用&#xff0c;它为我们提供了生存的食物。如今&#xff0c;它遇到了各种困难&#xff0c;例如气候变化的影响、缺乏工人以及全球流行病造成的中断。这些困难影响了耕作用水和土地的供应&#xff0c;而这些水和土地正变得越来越稀缺。…

skynet学习笔记03— 服务

01、API newservice(name, ...)&#xff1a; 阻塞的形势启动一个名为 name 的新服务&#xff0c;待start函数执行完后会返回这个服务的地址。uniqueservice(name, ...)&#xff1a;针对于当前节点&#xff0c;启动一个唯一服务&#xff08;相当于单例&#xff09;&#xff0c;…

springboot全局拦截sql异常

起因:非法用户可通过特定的输入(如输入内容超长)等操作,使后台逻辑发生错误,从而使后台sql语句暴露至前台,进而为sql攻击提供条件 处理流程:经查找com.mysql.cj.jdbc.exceptions的父类为SQLException,在全局异常处理类中增加如下配置,经测试不起作用 ExceptionHandler(SQLExce…

2024 款:最新前端技术趋势

Hello&#xff0c;大家好&#xff0c;我是 Sunday。 上一次的时候聊了 那么些已经落后的前端开发技术 。但是光知道什么技术落后了是不够的&#xff0c;咱们还得知道 前端最新的技术趋势是什么。所以&#xff0c;今天这篇文章&#xff0c;咱们就来聊一聊&#xff0c;2023 最新…

传统测试将被取代?AI测试现状及发展之思

近年来&#xff0c;我一直关注AI相关的测试&#xff0c;并积极参与多个全国性测试社区和社群。在这些社区中&#xff0c;我与不同公司和领域的测试专家交流探讨AI测试相关话题&#xff0c;包括业界顶尖公司的专家和国内知名测试学者。我也参加了多个大会&#xff0c;聆听了许多…

php性能追踪与分析

PHP扩展下载&#xff1a;https://pecl.php.net/package/xhprof php.ini配置 [xhprof] extensionxhprof xhprof.output_dir/temp/xhprof auto_prepend_file /temp/inject_xhprof.php if(php_sapi_name() cli) {return; }$xhprof_config[enabled]1;if(!empty($xhprof_config…

文生图模型测评之HPS v2

文章目录 1. 简介2. HPD v22.1 相关数据集介绍2.2 HPD v2 的构建2.2.1 prompt collection2.2.2 image collection2.2.3 preference annotation3. Human Preference Score v23.1 构建模型3.2 实验结果4. 结论及局限性论文链接:Human Preference Score v2: A Solid Benchmark fo…

uniapp+vue3+ts+vite+echarts开发图表类小程序,将echarts导入项目使用的详细步骤,耗时一天终于弄好了

想在uniapp和vue3环境中使用echarts是一件相当前卫的事情&#xff0c;官方适配的还不是很好&#xff0c;echarts的使用插件写的是有些不太清晰的&#xff0c;这里我花费了一天的时间&#xff0c;终于将这个使用步骤搞清楚了&#xff0c;并且建了一个仓库&#xff0c;大家可以直…

[西湖论剑 2022]real_ez_node

文章目录 前置知识EJS模板注入&#xff08;CVE-2022-29078&#xff09;原型链污染漏洞 &#xff08;CVE-2021-25928&#xff09;HTTP响应拆分攻击&#xff08;CRLF&#xff09; 解题过程代码审计构造payload 前置知识 EJS模板注入&#xff08;CVE-2022-29078&#xff09; EJS…

git命令汇总

1.git是基于ssh的代码管理工具,所以在git使用之前需要配置好ssh ssh配置教程 2.先创建仓库 3. git init在目标的git目录下创建仓库 4.git add .(或者写文件名) 5.git commit -m "标记信息" 持久化 6.git remote add origin gitgit.acwing.com:yaoaolong/11_5.git初次…