当前位置: 首页 > news >正文

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、…...

续二叉搜索树递归玩法

文章目录 一、插入递归二、寻找递归&#xff08;非常简单&#xff0c;走流程就行&#xff09;三、插入递归&#xff08;理解起来比较麻烦&#xff09; 先赞后看&#xff0c;养成习惯&#xff01;&#xff01;&#xff01;^ _ ^<3 ❤️ ❤️ ❤️ 码字不易&#xff0c;大家的…...

DDD 的四层领域模型是怎样的?包含哪些基础概念?

DDD的四层领域模型如下所示&#xff1a; 展现层&#xff1a;这一层负责向用户显示信息和解释用户命令&#xff0c;完成前端界面逻辑。并将用户请求传递给应用层。应用层&#xff1a;这一层是很薄的一层&#xff0c;负责协调领域层中的领域对象&#xff0c;组成具体应用场景。应…...

AI 在医疗保健领域的应用:技术、趋势和前景

人工智能&#xff08;AI&#xff09;在医疗保健领域的应用已经成为引人瞩目的发展方向&#xff0c;其在医学影像分析、疾病诊断和个性化治疗等方面展现出了巨大潜力。本文将深入探讨这些技术应用和未来的发展趋势。 医学影像分析 医学影像分析是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个关键字&#xff0c;C语言32个关键字 2. 命名空间 在C/C中&#xff0c;变量、函数和后面要学到的类都是大量存在的&#xff0c;这些变量、函数和类的名称都将存在于全局作用域中&#xff0c;可能会导致很多冲突。使用命名空间的目的就是对标识符的名…...

一些题目学习

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

【Linux】寿司线程池{单例模式之懒汉模式下的线程池}

文章目录 回顾单例模式0.多线程下的单例模式的意义1.什么是单例模式1.0设计模式1.1C单例模式的介绍及原理1.2拷贝构造和赋值重载的处理1.3if (nullptr ptr)&#xff0c;nullptr放在比较运算符的前面?1.4实现单例模式的方式 2.实现懒汉方式的单例模式2.1单线程的单例模式2.2多…...

Docker资源管理和分配指南

什么是cgroup&#xff1f; cgroups其名称源自控制组群&#xff08;control groups&#xff09;的简写&#xff0c;是Linux内核的一个功能&#xff0c;用来限制、控制与分离一个进程组&#xff08;如CPU、内存、磁盘输入输出等&#xff09;。 什么是Docker资源限制&#xff1f;…...

为什么索引的底层结构是B+树

B树 1.数据库与数据交互的单位是page,而B树的每个节点都是一个page,访问一个节点&#xff0c;就相当于进行了一次I/O操作。所以访问的节点越少&#xff0c;查找效率越大。而B树是矮胖的&#xff0c;查找深度也不会太大。 2.B树中的节点是有序存储的&#xff0c;对于范围查询、排…...

NLP学习路线指南总结

当然可以&#xff0c;以下是一份较为详细的NLP学习路线指南&#xff0c;帮助你逐步掌握自然语言处理的核心技术和应用。 一、基础知识与技能 语言学基础&#xff1a; 语言学基本概念&#xff1a;语音、语法、语义等。语言的层次与分类&#xff1a;语音学、音系学、句法学、语…...

试过了,ChatGPT确实不用注册就可以使用了!

看到官网说不用登录也可以直接使用ChatGPT 我们来试一下 直接打开官网 默认是直接进入了chatgpt3.5的聊天界面 之前是默认进的登录页面 聊一下试试 直接回复了&#xff0c;目前属于未登录状态&#xff0c;挺好&#xff01; 来试下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】哈希表(哈希映射,光速查找的魔法)

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、哈希1.1 哈希概念1.2 哈希函数1.3 哈希冲突 二、闭散列2.1 数据类型2.2 成员变量2.3 默认成员函数2.…...

「PHP系列」If...Else语句/switch语句

文章目录 一、If...Else语句1. 基本语法2. 带有 elseif 的语法3. 示例示例 1&#xff1a;基本 if...else 结构示例 2&#xff1a;使用 elseif示例 3&#xff1a;嵌套 if...else 结构 4. 注意事项 二、switch语句1. 基本语法2. 示例示例 1&#xff1a;基本 switch 结构示例 2&am…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...