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…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...
消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...
FFmpeg avformat_open_input函数分析
函数内部的总体流程如下: avformat_open_input 精简后的代码如下: int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...
RushDB开源程序 是现代应用程序和 AI 的即时数据库。建立在 Neo4j 之上
一、软件介绍 文末提供程序和源码下载 RushDB 改变了您处理图形数据的方式 — 不需要 Schema,不需要复杂的查询,只需推送数据即可。 二、Key Features ✨ 主要特点 Instant Setup: Be productive in seconds, not days 即时设置 :在几秒钟…...
