05-修建数据殿堂:Golang struct的艺术架构

news2024/11/25 15:42:27

在这里插入图片描述

📃个人主页:个人主页
🔥系列专栏:Golang基础
💬Go(又称Golang)是由Google开发的开源编程语言。它结合了静态类型的安全性和动态语言的灵活性,拥有高效的并发编程能力和简洁的语法。Go被设计用于构建可扩展、高性能的软件系统,具有优秀的内存管理和快速的编译速度,适用于Web开发、系统编程和云计算等领域。

文章目录

  • struct类型的声明
  • struct 的匿名字段

struct类型的声明

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

type person struct {
	name string
	age int
}

声明一个 struct 如此简单,上面的类型包含有两个字段:

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

使用 struct 看下面的代码:

type person struct {
	name string
	age int
}
var P person // P现在就是person类型的变量了
P.name = "张三" // 赋值"张三"给P的name属性.
P.age = 22 // 赋值"22"给变量P的age属性
fmt.Printf("my name is %s", P.name) // 访问P的name属性.

除了上面这种P的声明使用之外,还有另外几种声明使用方式:
1.按照顺序提供初始化值

P := person{"张三", 22}

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

P := person{age:22, name:"张三"}

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

P := new(person)

看一个完整的使用 struct 的例子:

package main
import "fmt"

// 声明一个新的类型
type person struct {
	name string
	age 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 的匿名字段

定义的时候是字段名与其类型一一对应,实际上Go支持只提供类型,而不写字段名的方式,也就是匿名字段,也称为嵌入字段。
当匿名字段是一个 struct 的时候,那么这个 struct 所拥有的全部字段都被隐式地引入了当前定义的这个 struct
看一个例子,让上面说的这些更具体化:

package main
import "fmt"

type Human struct {
	name string
	age int
	weight 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 = 46
	fmt.Println("His age is", mark.age)
	// 修改他的体重信息
	fmt.Println("Mark is not an athlet anymore")
	mark.weight += 60
	fmt.Println("His weight is", mark.weight)
}

看到 Student 访问属性 agename 的时候,就像访问自己所有用的字段一样,匿名字段就是这样,能够实现字段的继承。student 还能访问 Human 这个字段作为字段名,请看下面的代码:

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

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

package main
import "fmt"

type Skills []string
type Human struct {
	name string
	age int
	weight int
}
type Student struct {
	Human // 匿名字段,struct
	Skills // 匿名字段,自定义的类型string slice
	int // 内置类型作为匿名字段
	speciality string
}
func main() {
	// 初始化学生Jane
	jane := 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 = 3
	fmt.Println("Her preferred number is", jane.int)
}

从上面例子看出来 struct 不仅仅能够将 struct 作为匿名字段,自定义类型、内置类型都可以作为匿名字段,而且可以在相应的字段上面进行函数操作(如例子中的 append )。
这里有一个问题:如果 human 里面有一个字段叫做 phone ,而 student 也有一个字段叫做 phone ,那么该怎么办呢?
Go里面很简单的解决了这个问题,最外层的优先访问,也就是当通过 student.phone 访问的时候,是访问 student 里面的字段,而不是 human 里面的字段。
这样就允许去重载通过匿名字段继承的一些字段,当然如果想访问重载后对应匿名类型里面的字段,可以通过匿名字段名来访问。请看下面的例子:

package main
import "fmt"

type Human struct {
	name string
	age int
	phone string // Human类型拥有的字段
}
type Employee struct {
	Human // 匿名字段Human
	speciality string
	phone 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.coloradmin.cn/o/644119.html

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

相关文章

【送书福利-第十一期】清华社 IT BOOK 图书活动:前端、后端、C++、Python、人工智能 ~(共送5本)!

大家好,我是洲洲,欢迎关注,一个爱听周杰伦的程序员。关注公众号【程序员洲洲】即可获得10G学习资料、面试笔记、大厂独家学习体系路线等…还可以加入技术交流群欢迎大家在CSDN后台私信我! 本文目录 一、前言二、内容介绍1、《C高性…

chatgpt赋能python:Python怎么批量加注释

Python怎么批量加注释 作为一名有10年python编程经验的工程师,我觉得注释是程序开发过程中最为重要的一部分。注释能够提高代码的可读性,让其他开发者更容易理解和阅读代码,并且也方便后续维护和修改。但很多时候,我们可能需要在…

“怎样提高学习效率——介绍一款适合大学生的多功能平台【WRITE-BUG数字空间】“

作为一名大学生,我深刻体会到在学习和写作过程中所面临的诸多挑战和困难。在这个过程中,我发现了一个非常好用和实用的平台——【WRITE-BUG数字空间】。在我的使用经历中,Writebug帮助我一站式地管理和创作一些内容,包括学习作业、…

详解c++---set的介绍

目录标题 set容器的介绍set的构造函数insert函数的介绍find函数erase函数count函数lower_boundupper_boundmultiset set容器的介绍 set容器可以看成我们上一篇文章学习的K结构的搜索二叉树,所以set容器不仅可以存储数据,还可以对数据进行排序和去重&…

DAY22:二叉树(十二)二叉搜索树最小绝对差+二叉搜索树中的众数

文章目录 530.二叉搜索树的最小绝对差思路完整版双指针优化写法:不用创建数组遍历pre root为什么是指向当前遍历的前一个节点 501.二叉搜索树中的众数(这道题要知道普通二叉树怎么写)思路完整版普通二叉树的写法sort自定义比较函数cmp的情况…

[论文阅读笔记77]LoRA:Low-Rank Adaptation of Large Language Models

1. 基本信息 题目论文作者与单位来源年份LoRA: Low-Rank Adaptation of Large Language ModelsmicrosoftInternational Conference on Learning Representations2021 524 Citations 论文链接:https://arxiv.org/pdf/2106.09685.pdf 论文代码:https://…

IMX6ULL裸机篇之SPI实验

一. SPI 实验 SPI实验:学习如何使用 I.MX6U 的 SPI 接口来驱动 ICM-20608,读取 ICM-20608 的六轴数据。 本文学习 SPI主控芯片的代码编写。其中,包括SPI工作模式设置,主从模式设置,时钟配置等实现。 二. SPI 主控芯…

EBU5476 Microprocessor System Design 知识点总结_2 Arm architecture

ARM架构 ARM是一个指令集,前面讲的几个汇编指令这些都算做指令。 ARM公司有意思的地方是,他们不做ARM设备,他们只设计指令集架构,然后授权(知识产权核,IP核)给其他半导体厂商做。 A&#xff…

大数据分析与机器学习:技术深度与实例解析【上进小菜猪大数据系列】

上进小菜猪,沈工大软件工程专业,爱好敲代码,持续输出干货。 大数据分析与机器学习已成为当今商业决策和科学研究中的关键组成部分。本文将深入探讨大数据技术的背景和原则,并结合实例介绍一些常见的大数据分析和机器学习技术。 …

chatgpt赋能python:Python如何拟合直线:使用最小二乘法

Python如何拟合直线:使用最小二乘法 在数据分析和机器学习领域,拟合一个最佳的直线是很常见和有用的。Python中有很多库可以拟合直线,但最小二乘法是其中最常用的一种方法。在本文中,我们将介绍最小二乘法的原理和如何在Python中…

【Goalng 开源项目】还在手写重复的 CRUD 吗?这个开源项目帮你解放双手

gormpher Gormpher 介绍快速开始WebObject 接口约定查询单条数据删除单条数据创建单条数据编辑单条数据条件查询多条数据 进阶WebObject 配置项动态接口函数Gorm 泛型函数Admin 源码handleEditObjecthandleQueryObject Gormpher 介绍 gormpher 是一个轻量级的 Golang 库 基于…

编译原理及应用期末复习

杂 3型文法 右线性文法 短语、直接短语、句柄 、判断是否是二义性文法 1、证明是二义性文法:证明存在一个句子有两颗不同的语法树 ① 画语法分析树 ② 、NFA、DFA K:所有状态,包含初始状态 Σ:终结字符集 M:状…

chatgpt赋能python:Python中替换字符串成int类型的方法

Python中替换字符串成int类型的方法 简介 在Python编程过程中,经常需要对字符串进行处理。有时候我们需要将字符串中的某些字符替换成int型数据,以便于进行一定的数值计算或其他操作。本文将介绍如何在Python中找出需要替换的字符,并将其转…

Python实现将txt文件转换成对应的excel或csv文件

前言 本文是该专栏的第29篇,后面会持续分享python的各种干货知识,值得关注。 工作上可能会遇到这样的情况,使用python将某个txt文本,按照行索引和列索引转换成对应的excel文件或者是csv文件。 那对于这样的需求,用python如何实现呢?跟着笔者直接往下看解决方法。(附完…

UART协议总结

UART( Universal Asynchronous Receiver-Transmitter,通用异步收发器),是异步串行通信协议,用来传输串行数据。 1、UART原理说明 UART是全双工工作模式,其数据传输方法如下: 发送数据时&…

Hive 和 Oracle 中 Decode 函数的用法差异

前言 在数仓构建过程中,需要从业务那边进行数据的迁移!数仓大多数公司都是使用Hive,而业务那边使用的是Oracle数据库居多。最近就有个小伙伴在迁移的时候碰到了问题: 从报错来看,在使用 Decode() 函数的时候,传参有问题! 既然问题来了,我们就来解决一下呗,只有不断地…

基础知识学习---牛客网C++面试宝典(五)操作系统--第一节

1、本栏用来记录社招找工作过程中的内容,包括基础知识学习以及面试问题的记录等,以便于后续个人回顾学习; 暂时只有2023年3月份,第一次社招找工作的过程; 2、个人经历: 研究生期间课题是SLAM在无人机上的应…

LeetCode_Day6 | 四数相加||、赎金信、三数之和、四数之和!

LeetCode_哈希表 454.四数相加1.题目描述2.思路3.代码实现 383.赎金信1.题目描述2.暴力法3.哈希法思路代码实现 15.三数之和1.题目描述 454.四数相加 1.题目描述 详情leetcode链接 2.思路 解题步骤: 首先定义 map,key放a和b两数之和,valu…

神器CLIP:连接文本和图像,打造可迁移的视觉模型

2021年见证了vision transformer的大爆发,随着谷歌提出ViT之后,一大批的vision transformer的工作席卷计算机视觉任务。除了vision transformer,另外一个对计算机视觉影响比较大的工作就是Open AI在2021年1月份发布的DALL-E和CLIP&#xff0c…

chatgpt赋能python:一、Python在数据可视化中的应用

一、Python在数据可视化中的应用 Python是一种功能强大的编程语言,早已成为数据科学家和分析师的首选语言。数据可视化对于从数据中汲取信息和传达想法来说至关重要。Python也是数据可视化的理想工具之一。Python提供了许多强大的库,其中包括了一些流行…