# Go学习-Day5

文章目录

map

  • map是一个key-value的数据结构,又称为字段或关联数组

  • Golang自带的map是哈希表

  • 声明

go 复制代码
import "fmt"

func main() {
	var a map[int]int
	fmt.Println(a)
}
  • slice,map和func不能作为键值

  • 声明map是不会分配内存的,初始化需要用make

go 复制代码
import "fmt"

func main() {
	var a map[int]int
    a = make(map[int]int, 3)//可以存放三个键值对
	fmt.Println(a)
}
  • Go的map的键值是没有顺序的

  • 自动增长

go 复制代码
func main() {
	a := make(map[int]int)
	a[1] = 2
	a[2] = 1
	fmt.Println(a)
}
  • 直接初始化

go 复制代码
func main() {
	a := map[int]int{
		1: 1,
		2: 2,//这里也要,
	}
	fmt.Println(a)
}

增加和更新

  • 直接给键值赋值即可

删除

go 复制代码
delete(map, 1)//删除map键值为1的对,如果不存在不会操作
  • 如果要完全清空

  • 遍历key来删除,或者让map赋值一个新的map,给GC回收

查询

go 复制代码
val, flag := mp[1] //flag是bool,找到是true,没找到是false,val是对应值

遍历(for-range)

go 复制代码
func main() {
	a := map[int]int{
		1: 1,
		2: 2,
	}
	for k, v := range a {
		fmt.Println(k, v)
	}
	fmt.Println(a)
}

map切片

  • 同样slice的用法,注意map也要make就行,相当于在底层维护一个map类型的数组

关于哈希表遍历的一点看法

  • 大概是这样的,在底层有一个迭代器链表,或者,有一个指针数组,每次存放一个指针,迭代器依次访问这些指针,但是在添加元素的时候, 会rehash,导致顺序变化。所以Go的设计者把他设置成无序,每次都打乱这个数组,防止程序员误用哈希map

对map的key排序

  • 将键值追加到切片内,然后对切片排序

go 复制代码
import (
	"fmt"
	"sort"
)

func main() {

	mp := make(map[int]int, 10)
	mp[1] = 2
	mp[3] = 1
	mp[2] = 5
	mp[5] = 6
	var keys []int //切片
	for key, _ := range mp {
		keys = append(keys, key)
	}

	sort.Ints(keys)
	fmt.Println(keys)
}
  • map是引用类型

结构体与OOP

声明、初始化、序列化

  • go语言是用struct来面向对象的

  • 声明

go 复制代码
type Node struct {
	X int
	Y int
}

func main() {

	var a Node//空间自动分配
	fmt.Println(a)

}
//输出{0 0}
  • 赋值

go 复制代码
func main() {

	var a Node
	a.X = 1
	a.Y = 2
	fmt.Println(a)

}
//输出{1 2}
  • 初始化

go 复制代码
//方法一
a := Node{1, 2}

//方法二
ptr *Node = new(Node)
(*ptr).X = 1
(*ptr).Y = 2
//--------
func main() {

	var ptr *Node = new(Node)
	(*ptr).X = 1
	(*ptr).Y = 2
	fmt.Println(*ptr)

}
//---底层自动识别,这样也可以
func main() {

	var ptr *Node = new(Node)
	ptr.X = 1
	ptr.Y = 2
	fmt.Println(*ptr)
}
//方法三
var node *Node = &Node{}
  • 结构体的所有字段在内存中是连续的

  • 两个结构体的字段类型完全相同的话可以强制类型转换

  • 用type struct1 struct2给struct2取别名,相当于定义了一个新的类型,两者之间可以强制类型转换,但是不能直接赋值

  • struct的每个字段上可以写上一个tag,该tag可以通过反射机制获取,常见于序列化和反序列化

  • 复习一个点,Go没有public和private,所以用首字母大写和小写来确定是公共的还是私有的

  • 序列化:对象转json字符串

  • 反序列化:json字符串转对象

  • 动手

go 复制代码
import (
	"encoding/json"
	"fmt"
)

type Node struct {
	Name     string
	Password string
}

func main() {

	a := Node{
		"aaaaaa",
		"123456",
	}

	str, _ := json.Marshal(a)
	fmt.Println(a)
	fmt.Println(string(str))
}
//输出
//{aaaaaa 123456}
//{"Name":"aaaaaa","Password":"123456"}
  • 但是这种大写的变量很多客户端不习惯,所以使用tag,如果使用小写,就无法被结构体外部函数使用,无法序列化

go 复制代码
import (
	"encoding/json"
	"fmt"
)

type Node struct {
	Name     string `json:"name"`
	Password string `json:"password"`
}

func main() {

	a := Node{
		"aaaaaa",
		"123456",
	}

	str, _ := json.Marshal(a)
	fmt.Println(a)
	fmt.Println(string(str))
}
//输出
//{aaaaaa 123456}
//{"name":"aaaaaa","password":"123456"}

方法

  • 方法是作用在指定类型上的函数

go 复制代码
func (a Node) ok() {
    fmt.Println("ok")
}
//这个函数绑定给了Node
//调用
var a Node
p.ok()
  • 动手

go 复制代码
import (
	"fmt"
)

type Node struct {
	Name     string `json:"name"`
	Password string `json:"password"`
}

func (a Node) ok() {
	fmt.Println(a.Name)
}
func main() {

	a := Node{
		"aaaaaa",
		"123456",
	}

	a.ok()
}
//输出了Node的名字
  • 这个方法只能用指定类型来调用,不能直接调用

  • 如果想要修改原来的参数,我们使用结构体指针,并且这更常用,不用深拷贝,速度更快

go 复制代码
type Node struct {
	Name     string `json:"name"`
	Password string `json:"password"`
}

func (a *Node) ok() {
	a.Name = "bbbb"
}
func main() {

	a := Node{
		"aaaaaa",
		"123456",
	}

	a.ok()//编译器底层自动识别变为&a

	fmt.Println(a)
}
  • 可以通过实现String方法,可以自定义格式化输出

工厂模式

  • 类似于构造函数,在结构体所在包下写相应构造的函数,返回结构体指针,这样就可以在结构体私有的情况下,在其他包调用这个函数直接返回结构体对象
相关推荐
alfiy10 分钟前
Elasticsearch学习笔记(六)使用集群令牌将新加点加入集群
笔记·学习·elasticsearch
wjs202415 分钟前
Chrome 浏览器:现代网络浏览的先锋
开发语言
爱学的小涛20 分钟前
【NIO基础】基于 NIO 中的组件实现对文件的操作(文件编程),FileChannel 详解
java·开发语言·笔记·后端·nio
吹老师个人app编程教学21 分钟前
详解Java中的BIO、NIO、AIO
java·开发语言·nio
爱学的小涛21 分钟前
【NIO基础】NIO(非阻塞 I/O)和 IO(传统 I/O)的区别,以及 NIO 的三大组件详解
java·开发语言·笔记·后端·nio
北极无雪25 分钟前
Spring源码学习:SpringMVC(4)DispatcherServlet请求入口分析
java·开发语言·后端·学习·spring
望森FPGA39 分钟前
HDLBits中文版,标准参考答案 |3.1.1 Basic Gates | 基本门电路
学习·fpga开发
JavaGPT1 小时前
prometheus学习笔记之PromQL
笔记·学习·prometheus
AI视觉网奇1 小时前
pymeshlab 学习笔记
开发语言·python
纪伊路上盛名在1 小时前
如何初步部署自己的服务器,达到生信分析的及格线
linux·运维·服务器·python·学习·r语言·github