GO语言-07派生类型:map和结构体(上)

简介: 自己学习Go语言学习过程中的记录与总结,希望对你能有帮助。第七篇(上):学习Go语言的Map,以及使用type定义自己的类型,包括type+struct定义结构体
初心是记录和总结,自己学习Go语言的历程。如果能帮助到你,这是我的荣幸。

map

Map的概念在任何程序语言都一样,存储key-value这样的内容,通过key可以查到对应的valuekey是唯一的。

语法:
var map[key的类型]value的类型

例子:

//定义一个map,这时候没有初始化是不能直接使用的
var province map[string]string
province["ZheJiang"] = "浙江" //报错
未初始化的Map赋值会报错: panic: assignment to entry in nil map,说我们正在操作一个空的Map

panic指的是Go语言遇到一个异常时候强制执行让程序终止的操作

map初始化的几种方法

  • 使用make函数
  • 使用new定义一个指针,然后使用*解析地址赋给定义的map
  • 定义时同时赋值
//初始化方式一:使用make进行创建,初始指定容量为2
province = make(map[string]string, 2)
province["ZheJiang"] = "浙江"
province["ShangHai"] = "上海"
province["BeiJing"] = "北京"
// 初始化方式二:new返回的是一个指针
var province map[string]string
pointMap := new(map[string]string) // 返回的是一个map指针,指针是存地址的
province = *pointMap // *号的作用是解析地址
province["ZheJiang"] = "浙江"
province["ShangHai"] = "上海"
province["BeiJing"] = "北京"
// 我们手动给它初始化了,也是可以的
province := map[string]string{"JiangSu": "江苏", "SiChuan": "四川"}

查询map中是够包含某个键

基于map名[key名]的方式,会返回value和一个bool类型,通过bool可以判断是否含有这个键

_, ok := province["ZheJiang"] //_只是一个占位符
fmt.Println(ok)               //true

value, ok := province["ZheJiang"]
fmt.Println(value) //浙江
fmt.Println(ok) //true

遍历整个map

通过range的方式遍历Map,可以获得map的keyvalue。单独获取keyvalue,我们可以通过_我们可以舍去不需要的数据来实现,示例代码如下:

// 遍历Map
for key, value := range province {
   fmt.Println(key, value)
}

遍历Key

// 遍历Key
for key,_ := range province {
   fmt.Println(key)
}

遍历Value

// 遍历value
for _, value := range province {
   fmt.Println(value)
}

删除Map中的元素

使用内置函数delete,通过key删除map元素

delete(province, "ShangHai")

type关键字

使用type我们可以自定义类型。这很有必要,因为我们需要描述一件事的事情的时候是需要描述很多内容。就像人,这个人会有年龄,名字。我们需要把人的概念抽出来,然后就可以用人来形容世界上所有的人,因为我们将年龄,名字这种共性的东西抽出来,形成人的概念了。而go语言中并没有这个变量类型,只有int可以表示年龄,string可以表示名字。如何定义人这个类型呢?使用typestruct,先了解一下type

语法:

我们可以自定义类型,使用go语言提供type关键字,例如:

type myInt int

type是定义了一个全新的类型。我们可以基于内置的基本类型定义,上面的例子就是基于int定义的新类型myInt。现在我们准备回答这个类型怎么定义,通过type + struct

struct 结构体

结构体有点类似于Java定义的类,里面有成员变量和方法。恰恰,在Go语言中方法就是一个类型,所以这和Java的类很像!,这样有助于我们开始理解struct。拿个例子,定义一个person类型,它可以描述人的年龄和姓名。

语法:

type 类型名 struct {
    字段名 字段类型
    字段名 字段类型
    ...
} 

解读:type是用来表示自定义类型的,struct可以帮助我们使用多个字段类型来组成类型名这个类型,其实我们就是在定义一个复合类型,这个类型的名字最终交类型名

定义person类型:

type person struct{
    name string //描述姓名
    age int //描述年龄
}

定义完成之后,我们来定义一个person类型的变量取名为people,当输出people的时候,我们会发现该类型中包含的类型都被自动初始化了。

var people person
fmt.Println(people) //{ 0}

定义的变量我们可以通过.的方式访问到结构体中的字段名,并给与一些赋值的操作。

//通过类型.字段名的方式结构体的字段
people.name = "chengyunlai"
people.age = 18
fmt.Println(people) // {chengyunlai 18}

使用new的方式定义

我们使用new的方式定义的时候,我们知道其实返回的是一个指针,所以people2其实是一个person类型的指针,里面存放的是地址,当我们打印的时候可以发现前面是带了个&符号。

那我们当然知道*是解析地址的作用,在前面加了个*,发现打印出来就是实际的值

// 定义2 使用new返回指针的方式定义
people2 := new(person)
fmt.Println(people2)        //&{ 0}
fmt.Println(*(people2))     //{ 0}
fmt.Println((*people2).age) // 0

其实不用这么麻烦,Go语言为我们准备了语法糖,看代码

people2.age = 18 // 相当于(*people2).age = 18
fmt.Println(people2.age)

结构体里放方法?

学过java的人,又了解过go语言中方法其实是一个类型的时候,会很开心的想到在结构体里放方法,比如说设置一个setter方法,通过方法传参的方式设置nameage

type person struct {
   name    string //描述姓名
   age     int    //描述年龄
   setNameAndAge func(p *person, name string, age int)
}
这个需要用到指针的知识,小伙伴们可以自己尝试,我就不挖坑了,因为我试过了。指针传递过来的地址保证了我们操作的是同一个地址。

解读:
这里我们定义了一个方法setName func(p *person, name string, age int),方法名为setName,因为go没有this的用法,所以我们把对操作,写进了第一个变量中,我们需要做的是给nameint赋值,所以还定义了两个传入的参数。

使用:

var people person //定义person类型的变量为people

people.setNameAndAge = func(p *person, name_ string, age_ int) {
   p.name = name_
   p.age = age_
   fmt.Printf("%p\n", p) //0xc0000543c0
}

people.setNameAndAge(&people, "张三", 15)
fmt.Printf("%p\n", &people) //0xc0000543c0
fmt.Println(people) //{张三 15 0xa4fc80}

解读:
由于我尝试在结构体中写方法,但是失败了,失败的原因看语法就能明白,里面只能定义。所以只能实例化(var people person),像people.字段名的方法进行方法的赋值(确实感觉笨笨的~),当然我们可以考虑将方法抽出来这样将方法名赋值就行。后面我们会说一下go语言应对这种情况的解决办法。但是我这个思想还是挺重要的

people.setNameAndAge(&people, "张三", 15)传入了操作的地址,以及我想赋值的变量值,由于我的方法已经定义好了,在方法中我特地打印了一下地址,可以发现两个打印输出的地址是一样的,这就是指针的作用。

最后输出了fmt.Println(people) //{张三 15 0xa4fc80} 发现尝试成功!

目录
相关文章
|
1月前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
162 1
|
1月前
|
Java 编译器 Go
【Golang】(5)Go基础的进阶知识!带你认识迭代器与类型以及声明并使用接口与泛型!
好烦好烦好烦!你是否还在为弄不懂Go中的泛型和接口而烦恼?是否还在苦恼思考迭代器的运行方式和意义?本篇文章将带你了解Go的接口与泛型,还有迭代器的使用,附送类型断言的解释
160 3
|
1月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
152 1
|
1月前
|
存储 Java Go
【Golang】(3)条件判断与循环?切片和数组的关系?映射表与Map?三组关系傻傻分不清?本文带你了解基本的复杂类型与执行判断语句
在Go中,条件控制语句总共有三种if、switch、select。循环只有for,不过for可以充当while使用。如果想要了解这些知识点,初学者进入文章中来感受吧!
120 1
|
3月前
|
Cloud Native 安全 Java
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
286 1
|
3月前
|
Cloud Native Go API
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
359 0
|
3月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
232 0
|
3月前
|
Cloud Native Java 中间件
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
212 0
|
3月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
305 0
|
3月前
|
数据采集 Go API
Go语言实战案例:多协程并发下载网页内容
本文是《Go语言100个实战案例 · 网络与并发篇》第6篇,讲解如何使用 Goroutine 和 Channel 实现多协程并发抓取网页内容,提升网络请求效率。通过实战掌握高并发编程技巧,构建爬虫、内容聚合器等工具,涵盖 WaitGroup、超时控制、错误处理等核心知识点。
下一篇
oss云网关配置