Golang基础-9
Go语言基础
介绍
基础
介绍
- 本文介绍Go语言中自定义类型、结构体定义、结构体声明、结构体初始化、字段访问与修改、匿名结构体、结构体嵌套、初始化函数定义等相关知识。
基础
结构体
- 相对于其它的数据类型有唯一的类型,Go语言中提供结构体类型,结构体是由一个或多个任意类型的值聚合成的实体,每个值都是结构体的成员。
自定义类型
- Go语言中使用 type 定义一种新的类型,也就是类型别名,由于Go语言中对数据类型检查比较严,认为是新类型,两个类型不能自动隐式转换,需要强制转换。
package mainimport "fmt"type MyInt int // 将int重新自定义为新类型(起别名)func main() {var a int = 10var b MyInt = 20fmt.Printf("a type: %T, value %v\n", a, a)fmt.Printf("b type: %T, value %v\n", b, b)// invalid operation: a == b (mismatched types int and MyInt)// fmt.Println("a == b: ", a == b)// 强制转换fmt.Println("a == b: ", a == int(b))
}
输出结果
a type: int, value 10
b type: main.MyInt, value 20
a == b: false
结构体定义
- 结构体属于自定义数据类型、使用 struct 关键字声明,格式如下:
type 类型名 struct {
字段1 字段1类型
字段2 字段2类型
…
}
结构体声明
- 将非指针变量声明为已经定义的结构体类型,默认初始化为哥字段对应的初始值。
- 也可以使用指针直接声明结构体指针变量,此指针变量被初始化为 nil。
package mainimport "fmt"type Computer struct {id intuser stringupdate bool
}func main() {var a Computer // 声明结构体实例fmt.Printf("a type: %T, value: %v\n", a, a)
}
输出结果
a type: main.Computer, value: {0 false}
结构体初始化
- 结构体创建的变量称为对应结构体的实例或者对象。Go语言中结构体有多种初始化方式,以下将详细说明。
- 使用各类型默认值初始化。
package mainimport "fmt"type Computer struct {id int // 默认为0user string // 默认为空update bool // 默认为false
}func main() {var a Computer = Computer{}fmt.Printf("a type: %T, value: %v\n", a, a)
}
输出结果
a type: main.Computer, value: {0 false}
- 使用字面量初始化。
package mainimport "fmt"type Computer struct {id intuser stringupdate bool
}func main() {var a Computer = Computer{ // 所有字段初始化1001,"Admin",true, // 注意最后的类型末尾逗号不能省略}fmt.Printf("a type: %T, value: %v\n", a, a)// 初始化指定字段,未指定的字段使用各字段类型默认初始化值var b Computer = Computer{id: 1002, update: true}fmt.Printf("b type: %T, value: %v\n", b, b)// 分别初始化结构体字段值var c Computerc.id = 1003c.user = "root"fmt.Printf("c type: %T, value: %v\n", c, c)// 自动推导类型并初始化d := Computer{ // 必须所有字段初始化1004,"pin",true, // 注意最后的类型末尾逗号不能省略}fmt.Printf("d type: %T, value: %v\n", d, d)
}
输出结果
a type: main.Computer, value: {1001 Admin true}
b type: main.Computer, value: {1002 true}
c type: main.Computer, value: {1003 root false}
d type: main.Computer, value: {1004 pin true}
- 初始化结构体指针。
package mainimport "fmt"type Computer struct {id intuser stringupdate bool
}func main() {// 声明结构体指针,未初始化,默认指向nilvar a *Computerfmt.Printf("a type: %T, value: %v\n", a, a)// 使用 new 实例化结构体指针,默认初始化var b *Computer = new(Computer)fmt.Printf("b type: %T, value: %v\n", b, b)b.id = 1005 b.user = "pwd"fmt.Printf("init b type: %T, value: %v\n", b, b)// 取地址实例化c := &Computer{1006,"ccc",true,}fmt.Printf("c type: %T, value: %v\n", c, c)
}
输出结果
a type: *main.Computer, value:
b type: *main.Computer, value: &{0 false}
init b type: *main.Computer, value: &{1005 pwd false}
c type: *main.Computer, value: &{1006 ccc true}
字段访问与修改
package mainimport "fmt"type Computer struct {id intuser stringupdate bool
}func main() {// 声明并初始化普通变量var v Computer = Computer{id: 1007, update: true}// 访问结构体字段fmt.Println("read v: id = ", v.id, ", user = ", v.user, ", update = ", v.update)// 修改结构体字段v.id = 1008fmt.Println("modify v: id = ", v.id, ", user = ", v.user, ", update = ", v.update)// 使用取地址实例化结构体指针c := &Computer{1009,"ccc",true,}// 访问结构体字段fmt.Println("read c: id = ", c.id, ", user = ", c.user, ", update = ", c.update)// 修改结构体字段// 对于结构体指针,修改字段时这两种写法均可c.id = 1010 // 会自动转换为 (*c).id = 1010(*c).user = "pwd"fmt.Println("modify c: id = ", c.id, ", user = ", c.user, ", update = ", c.update)
}
输出结果
read v: id = 1007 , user = , update = true
modify v: id = 1008 , user = , update = true
read c: id = 1009 , user = ccc , update = true
modify c: id = 1010 , user = pwd , update = true
匿名结构体
- 在使用时直接使用 struct 关键字定于并初始化结构体变量或结构体指针变量,简单理解就是结构体没有指定名称,所以称之为匿名结构体。
package mainimport ("fmt""reflect"
)func main() {// 匿名结构体变量addr := struct {ip stringport int}{"127.0.0.1", 9999}fmt.Println("net addr: ", addr, ", type: ", reflect.TypeOf(addr))// 匿名结构体指针变量addr2 := &struct {ip stringport int}{"127.0.0.1", 8080}fmt.Println("net addr2: ", addr2, ", type: ", reflect.TypeOf(addr2))// 匿名结构体数组addr3 := [...]struct {ip stringport int}{{"127.0.0.1", 1111}, {"127.0.0.1", 2222}, {"127.0.0.1", 3333}}fmt.Println("net addr3: ", addr3, ", type: ", reflect.TypeOf(addr3))// 匿名结构体切片addr4 := []struct {ip stringport int}{{"127.0.0.1", 4444}, {"127.0.0.1", 5555}}fmt.Println("net addr4: ", addr4, ", type: ", reflect.TypeOf(addr4))
}
输出结果
net addr: {127.0.0.1 9999} , type: struct { ip string; port int }
net addr2: &{127.0.0.1 8080} , type: *struct { ip string; port int }
net addr3: [{127.0.0.1 1111} {127.0.0.1 2222} {127.0.0.1 3333}] , type: [3]struct { ip string; port int }
net addr4: [{127.0.0.1 4444} {127.0.0.1 5555}] , type: []struct { ip string; port int }
结构体嵌套
- 结构体也可以嵌套,这对于抽象出的公共数据多次复用非常易用。
- 嵌套分为命名嵌套和匿名嵌套。不能嵌套两个相同名称的结构体。
- 在不同的结构体中有相同名称的字段时,不能使用匿名嵌套。
package mainimport "fmt"type Base struct {name stringid int
}// 定义结构体命名嵌套
type Cpu struct {cpuType intbase Base
}// 定义结构体匿名嵌套
type Memory struct {mem intBase
}// 定义结构体命名嵌套指针
type Net struct {chose intbase *Base
}// 定义结构体匿名嵌套指针
type View struct {color int*Base
}func PointerStructVar() {// 命名嵌套结构体指针声明并初始化所有变量a := Net{1, &Base{"NNN", 10000}}fmt.Println("a: ", a)fmt.Printf("a.chose=%v, a.name=%v, a.id=%v\n", a.chose, a.base.name, a.base.id)// 命名嵌套结构体指针指定字段初始化b := Net{chose: 2, base: &Base{"NNNNNN", 20000}}fmt.Println("b: ", b)fmt.Printf("b.chose=%v, b.name=%v, b.id=%v\n", b.chose, b.base.name, b.base.id)// 命名嵌套结构体指针修改字段a.base.id = 10001(*a.base).name = "NNM"fmt.Println("modify a: ", a)fmt.Printf("a.chose=%v, a.name=%v, a.id=%v\n", a.chose, a.base.name, a.base.id)// 匿名嵌套结构体指针声明并初始化所有变量aa := View{100, &Base{"XXX", 10000}}fmt.Println("aa: ", aa)fmt.Printf("aa.color=%v, aa.name=%v, aa.id=%v\n", aa.color, aa.name, aa.id)// 匿名嵌套结构体指针指定字段初始化bb := View{color: 200, Base: &Base{name: "XXXXXX", id: 20000}}fmt.Println("bb: ", bb)fmt.Printf("bb.color=%v, bb.name=%v, bb.id=%v\n", bb.color, bb.name, bb.id)// 匿名嵌套结构体指针修改字段aa.id = 10001fmt.Println("modify aa: ", aa)fmt.Printf("aa.color=%v, aa.name=%v, aa.id=%v\n", aa.color, aa.name, aa.id)}func NormalStructVar() {// 命名嵌套结构体声明并初始化所有变量a := Cpu{1, Base{"intel", 10000}}fmt.Println("a: ", a)// 命名嵌套结构体指定字段初始化b := Cpu{cpuType: 2, base: Base{"AMD", 20000}}fmt.Println("b: ", b)// 命名嵌套结构体修改字段a.base.id = 10001fmt.Println("modify a: ", a)// 匿名嵌套结构体声明并初始化所有变量aa := Memory{100, Base{"DDR333", 10000}}fmt.Println("aa: ", aa)// 匿名嵌套结构体指定字段初始化bb := Memory{mem: 200, Base: Base{name: "DDR400", id: 20000}}fmt.Println("bb: ", bb)// 匿名嵌套结构体修改字段aa.id = 10001fmt.Println("modify aa: ", aa)
}func main() {// 结构体变量操作NormalStructVar()fmt.Println("==================================")// 结构体指针变量操作PointerStructVar()
}
输出结果
a: {1 {intel 10000}}
b: {2 {AMD 20000}}
modify a: {1 {intel 10001}}
aa: {100 {DDR333 10000}}
bb: {200 {DDR400 20000}}
modify aa: {100 {DDR333 10001}}
==================================
a: {1 0xc000008048}
a.chose=1, a.name=NNN, a.id=10000
b: {2 0xc000008060}
b.chose=2, b.name=NNNNNN, b.id=20000
modify a: {1 0xc000008048}
a.chose=1, a.name=NNM, a.id=10001
aa: {100 0xc000008078}
aa.color=100, aa.name=XXX, aa.id=10000
bb: {200 0xc000008090}
bb.color=200, bb.name=XXXXXX, bb.id=20000
modify aa: {100 0xc000008078}
aa.color=100, aa.name=XXX, aa.id=10001
初始化函数定义
- 在Go语言中,通常定义一个或多个New函数用于创建结构体实例。
package mainimport "fmt"type Base struct {name stringid int
}func NewBase(name string, id int) *Base {return &Base{name, id}
}func NewName(nm string) *Base {return &Base{name: nm}
}func NewId(num int) *Base {return &Base{id: num}
}func main() {a := NewBase("QWER", 100)fmt.Println("a: ", a)
}
输出结果
a: &{QWER 100}
起始
相关文章:
Golang基础-9
Go语言基础 介绍 基础 结构体 自定义类型 结构体定义 结构体声明 结构体初始化 字段访问与修改 匿名结构体 结构体嵌套 初始化函数定义 介绍 本文介绍Go语言中自定义类型、结构体定义、结构体声明、结构体初始化、字段访问与修改、匿名结构体、结构体嵌套、初始化…...

Vue基础知识:路由的封装抽离,路由模块的封装抽离的好处是什么?,如何快速的引入组件,基于@指代src目录,从src目录出发找组件
如果将所有的路由配置都存放在main.js中,是非常有问题的,杂且乱。所以我们要将路由模块进行抽离,这样有利于:拆分模块,利于维护。大致的做法就是将路由相关的东西放到router这个文件夹的index.js中,而将来只…...

插入排序---算法
1、算法概念 插入排序:它的工作原理是通过构建有序排序,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置插入。 2、算法步骤 将第一待排序序列第一个元素看作一个有序序列,把第二个元素到最后一个元素当成是…...
Vue3 Vite 整合组件脚手架笔记
序号更新时间备注12024.04.03初始化整理笔记 目录 一、安装运行命令二、相关依赖内容 1、http客户端 - alova2、国际化 - I18n3、时间管理 - moment4、pdf预览 - pdfjs-dist5、doc预览 - docx-preview6、请求参数处理 - qs7、全局状态管理 - Pinia8、路由管理 - vue-router9、…...

续二叉搜索树递归玩法
文章目录 一、插入递归二、寻找递归(非常简单,走流程就行)三、插入递归(理解起来比较麻烦) 先赞后看,养成习惯!!!^ _ ^<3 ❤️ ❤️ ❤️ 码字不易,大家的…...

DDD 的四层领域模型是怎样的?包含哪些基础概念?
DDD的四层领域模型如下所示: 展现层:这一层负责向用户显示信息和解释用户命令,完成前端界面逻辑。并将用户请求传递给应用层。应用层:这一层是很薄的一层,负责协调领域层中的领域对象,组成具体应用场景。应…...
AI 在医疗保健领域的应用:技术、趋势和前景
人工智能(AI)在医疗保健领域的应用已经成为引人瞩目的发展方向,其在医学影像分析、疾病诊断和个性化治疗等方面展现出了巨大潜力。本文将深入探讨这些技术应用和未来的发展趋势。 医学影像分析 医学影像分析是AI在医疗领域中应用最广泛的领…...
SVG XML 格式定义图形入门介绍
SVG SVG means Scalable Vector Graphics. SVG 使用 XML 格式定义图形SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失SVG 是万维网联盟的标准 Hello World Use SVG in html and you can see: Link to the SVG file You can use <a> tag to link to the svg…...
MYSQL数据库的故障排除与优化
目录 一.MySQL单实例故障排查 故障现象1 故障现象 2 故障现象 3 故障现象 4 故障现象 5 故障现象 6 故障现象 7 故障现象 8 二.主从环境常见故障 1.故障一 2. 故障二 3. 故障三 三. 优化 1.SQL优化 2. 架构优化 3.硬件方面 1.1 关于CPU 1.2 关于内存 1.3 关…...

C++从入门到精通——入门知识
1. C关键字(C98) C总计63个关键字,C语言32个关键字 2. 命名空间 在C/C中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称都将存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的就是对标识符的名…...

一些题目学习
1.打开文件添加helloworld public class Saier {public static void main(String[] args){String path"C:\\Users\\sjg\\Desktop\\abc.txt";String text"hello world";try {File file new File(path);FileWriter fileWriter new FileWriter(file,true);…...

Linux上管理文件系统
Linux上管理文件系统 机械硬盘 机械硬盘由多块盘片组成,它们都绕着主轴旋转。每块盘片上下方都有读写磁头悬浮在盘片上下方,它们与盘片的距离极小。在每次读写数据时盘片旋转,读写磁头被磁臂控制着不断的移动来读取其中的数据。 所有的盘片…...

【Linux】寿司线程池{单例模式之懒汉模式下的线程池}
文章目录 回顾单例模式0.多线程下的单例模式的意义1.什么是单例模式1.0设计模式1.1C单例模式的介绍及原理1.2拷贝构造和赋值重载的处理1.3if (nullptr ptr),nullptr放在比较运算符的前面?1.4实现单例模式的方式 2.实现懒汉方式的单例模式2.1单线程的单例模式2.2多…...
Docker资源管理和分配指南
什么是cgroup? cgroups其名称源自控制组群(control groups)的简写,是Linux内核的一个功能,用来限制、控制与分离一个进程组(如CPU、内存、磁盘输入输出等)。 什么是Docker资源限制?…...
为什么索引的底层结构是B+树
B树 1.数据库与数据交互的单位是page,而B树的每个节点都是一个page,访问一个节点,就相当于进行了一次I/O操作。所以访问的节点越少,查找效率越大。而B树是矮胖的,查找深度也不会太大。 2.B树中的节点是有序存储的,对于范围查询、排…...
NLP学习路线指南总结
当然可以,以下是一份较为详细的NLP学习路线指南,帮助你逐步掌握自然语言处理的核心技术和应用。 一、基础知识与技能 语言学基础: 语言学基本概念:语音、语法、语义等。语言的层次与分类:语音学、音系学、句法学、语…...

试过了,ChatGPT确实不用注册就可以使用了!
看到官网说不用登录也可以直接使用ChatGPT 我们来试一下 直接打开官网 默认是直接进入了chatgpt3.5的聊天界面 之前是默认进的登录页面 聊一下试试 直接回复了,目前属于未登录状态,挺好! 来试下ChatGPT4 跳转到了登录页面 目前来看gpt4还…...

CANoe自带的TCP/IP协议栈中TCP的keep alive机制是如何工作的
TCP keep alive机制我们已经讲过太多次,车内很多控制器的TCP keep alive机制相信很多开发和测试的人也配置或者测试过。我们今天想知道CANoe软件自带的TCP/IP协议栈中TCP keep alive机制是如何工作的。 首先大家需要知道TCP keep alive的参数有哪些?其实就三个参数:CP_KEEP…...

【C++练级之路】【Lv.18】哈希表(哈希映射,光速查找的魔法)
快乐的流畅:个人主页 个人专栏:《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火,在为久候之人燃烧! 文章目录 引言一、哈希1.1 哈希概念1.2 哈希函数1.3 哈希冲突 二、闭散列2.1 数据类型2.2 成员变量2.3 默认成员函数2.…...
「PHP系列」If...Else语句/switch语句
文章目录 一、If...Else语句1. 基本语法2. 带有 elseif 的语法3. 示例示例 1:基本 if...else 结构示例 2:使用 elseif示例 3:嵌套 if...else 结构 4. 注意事项 二、switch语句1. 基本语法2. 示例示例 1:基本 switch 结构示例 2&am…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!
目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...