【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.mzph.cn/news/140600.shtml

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

相关文章

Ubuntu 20.04编译Chrome浏览器

本文记录chrome浏览器编译过程,帮助大家避坑qaq 官网文档:https://chromium.googlesource.com/chromium/src//main/docs/linux/build_instructions.md 一.系统要求 一台64位的英特尔机器,至少需要8GB的RAM。强烈推荐超过16GB。至少需要100…

基于Matlab+ AlexNet神经网络的动物识别系统

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 基于Matlab和AlexNet神经网络的动物识别系统可以用于自然图像识别等场景,以下是一个基本的介绍设计步骤…

项目笔记记录

一、node下载版本报错:npm install --legacy-peer-deps 二、Scheduled: 任务自动化调度 Scheduled 标记要调度的方法的注解,必须指定 cron,fixedDelay或fixedRate属性之一 fixedDelay:固定延迟 延迟执行任务,任务在…

stm32单片机无法驱动sg90舵机

如果使用调试器调试sg90的时候,也许会遇到舵机没有反应的情况,这个时候可以把调试器断开,直接使用usb线接到单片机上面,舵机就会开始动,需要注意的是3.3V也是可以驱动sg90的,虽然标的是5V

Linux 图形化界面

Part I: Linux 系统概述 什么是 LinuxLinux 的历史和版本Linux 发行版介绍Linux 的优缺点 Part II: Linux 安装与配置 5. 硬件要求与准备工作 6. 安装 Linux 操作系统 7. Linux 系统初始化设置 8. Linux 系统更新与升级 9. Linux 基础配置 Part III: Linux 命令行 10. Linux…

论文笔记:Deep Trajectory Recovery with Fine-Grained Calibration using Kalman Filter

TKDE 2021 1 intro 1.1 背景 用户轨迹数据对于改进以用户为中心的应用程序很有用 POI推荐城市规划路线规划由于设备和环境的限制,许多轨迹以低采样率记录 采样的轨迹无法详细说明物体的实际路线增加了轨迹中两个连续采样点之间的不确定性——>开发有效的算法以…

高频SQL50题(基础班)-4

文章目录 主要内容一.SQL练习题1.1789-员工的直属部门代码如下(示例): 2.610-判断三角形代码如下(示例): 3.180-连续出现的数字代码如下(示例): 4.1164-指定日期的产品价格代码如下(示例&#x…

Java实现音频转码,WAV、MP3、AMR互转

1.背景 最近在集成一款产品支持语音双向对讲,首先是采集小程序的音频下发给设备端,然后可以控制设备录音生成音频链路让小程序播放。在这个过程中发现,设备除了AMR格式的音频外,其他的音频都不支持,而微信小程序有不支…

【Linux】虚拟机连不上外网 (ping www.baidu.com不通)

进入linux系统,打开终端,ping www.baidu.com 发现ping不通 首先我连接的是nat模式 查看是否连接上自己本机的网 切换root用户 使用 ifconfig 命令查看是eth0 还是 ens33 vi /etc/sysconfig/network-scripts/ifcfg-ens33 BOOTPROTOstatic ONBOOTyes …

蓝桥杯每日一题2023.11.10

“蓝桥杯”练习系统 (lanqiao.cn) 题目描述 题目分析 对于此题:我们看到题目要求尽可能大,会联想到二分,注意切出的一定为正方形,其能切出的个数为(h[i] / x) * (w[i] / x),将所有的个数与要求的个数进行对比&#x…

uniapp在IOS手机下解决时间nan-an-nan问题

废话不多说,直接上代码 if (uni.getSystemInfoSync().platform ios) {// 解决ios手机时间格式化NaN问题date date.replace(/-/g, /);}

springcloudalibaba入门详细使用教程

目录标题 一、简介二、SpringCloud Alibaba核心组件2-1、Nacos (配置中心与服务注册与发现)2-2、Sentinel (分布式流控)2-3、RocketMQ (消息队列)/RabbitMq/kafka2-4、Seata (分布式事务)2-5、Dubbo (RPC) 三、为什么大家看好 Spring Cloud Alibaba3-1、阿里巴巴强大的技术输出…

k8s安装ingress-nginx

目录 前言准备helm安装包修改values.yaml安装ingress测试功能 前言 k8s集群搭建参考: https://blog.csdn.net/centrl/article/details/134291473 整合helm参考: https://blog.csdn.net/centrl/article/details/134293363 安装loadbalance参考&#xff1…

(头哥)多表查询与子查询

目录 第1关:查询每个学生的选修的课程信息 第2关:查询选修了“数据结构”课程的学生名单 第3关:查询“数据结构”课程的学生成绩单 第4关:查询每门课程的选课人数 第5关:查询没有选课的学生信息 第6关&#xff1a…

大语言模型的关键技术(二)

一、Transformer 语言模型存在明显的扩展效应: 更大的模型/数据规模和更多的训练计算通常会导致模型能力的提升。 1、扩展效应的原因: 模型规模:增加模型的规模,即增加模型的参数数量和层数,通常会提高模型的表示能力…

ROS基础知识复习

【置顶】感谢参考:https://zhuanlan.zhihu.com/p/662074088 0.背景 工作一年多没有做 ROS 相关的开发了,最近找工作想做回这一块来,根据参考内容,抽时间给这边的基础知识敲一遍复习一下 1.环境检查 打开了之前的笔记本&#x…

mysql讲解2 之事务 索引 以及权限等

系列文章目录 mysql 讲解一 博客链接 点击此处即可 文章目录 系列文章目录一、事务1.1 事务的四个原则1.2 脏读 不可重复读 幻读 二、索引三,数据库用户管理四、mysql备份 一、事务 1.1 事务的四个原则 什么是事务 事务就是将一组SQL语句放在同一批次内去执行 如果一个SQ…

webpack提升构建速度

目录 配置优化减少 resolve 的解析把 loader 应用的文件范围缩小减少 plugin 的消耗选择合适的 devtool 使用工具thread-loaderDLLPlugin 流程优化拆分构建步骤拆分项目代码 版本更新总结 前端项目随着时间推移和业务发展,页面可能会越来越多,或者功能和…

什么是安全平行切面

安全平行切面的定义 通过嵌入在端—管—云内部的各层次切点,使得安全管控与业务逻辑解耦,并通过标准化的接口为安全业务提供内视和干预能力的安全基础设施。安全平行切面是一种创新的安全体系思想,是实现“原生安全”的一条可行路径。 为什…

Excel下载、Excel上传,邮件发送Excel并带Char图表

Excel上传 前段&#xff1a;ExportToExcel、UploadExcel <!-- 模态框 -文件下载上传 --><div class"modal"><div class"modal-content family"><span class"close" onclick"ModalClose(modal)"></span>…