【Golang】关于Go中一些常用的知识介绍
一、哪些类型可以作为map的key ?
1、可比较的类型都可以作为map key
-
boolean 布尔值
-
numeric 数字 包括整型、浮点型,以及复数
-
string 字符串
-
pointer 指针 两个指针类型相等,表示两指针指向同一个变量或者同为nil
-
channel 通道 两个通道类型相等,表示两个通道是被相同的make调用创建的或者同为nil
-
interface 接口 两个接口类型相等,表示两个接口类型 的动态类型 和 动态值都相等 或者 两接口类型 同为 nil
-
structs、arrays 只包含以上类型元素
2、不能作为map key 的类型包括
-
slices
-
maps
-
functions
3、下面针对几种类型的比较做举例说明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | package main import ( "fmt" ) type Orange struct { Host string Port int } func main() { // 指针 orange1 := Orange{} orange2 := Orange{} op11 := &orange1 op12 := &orange1 op2 := &orange2 fmt.Println( "op11 == op12 :" , op11 == op12) // true fmt.Println( "op11 == op2 :" , op11 == op2) // false // 通道 ch1 := make( chan int, 1) ch2 := ch1 ch3 := make( chan int, 1) fmt.Println( "ch1 == ch2 :" , ch1 == ch2) // true fmt.Println( "ch1 == ch3 :" , ch1 == ch3) // false // 结构体 orange3 := Orange{} orange4 := Orange{} orange5 := Orange{ "host001" , 22} fmt.Println( "orange3 == orange4 :" , orange3 == orange4) // true fmt.Println( "orange3 == orange5 :" , orange3 == orange5) // false // 数组 a1 := [1]int{0} a2 := [1]int{0} fmt.Println( "a1 == a2 :" , a1 == a2) // true } |
输出结果
1 2 3 4 5 6 7 | op11 == op12 : true op11 == op2 : false ch1 == ch2 : true ch1 == ch3 : false orange3 == orange4 : true orange3 == orange5 : false a1 == a2 : true |
二、关于make及切片slice、映射map详解
内建函数 make 用来为 slice,map 或 chan 类型分配内存和初始化一个对象(注意:只能用在这三种类型上),使用make来创建slice,map,chanel说明如下:
1、make 创建slice
1 | make([]Type, len, cap) |
cap可以省略。当cap省略时,默认等于len。此外cap >= len >= 0的条件必须成立。例如,创建一个len和cap均为10的int型slice。
1 2 3 4 5 6 7 8 9 | // 长度为5,容量为10的slice,slice中的元素是int var slice_ []int = make([]int,5,10) fmt.Println(slice_) var slice_1 []int = make([]int,5) fmt.Println(slice_1) var slice_2 []int = []int{1,2} fmt.Println(slice_2) |
用第三个参数设置该slice的容量(即底层数组的长度)。如果能够预足容量,那么在slice中数据增长的过程中不需要更换底层数组(附带拷贝过程),这样效率更高。
2、make 创建 map
1 | make( map [keyType] valueType, size) |
keyType表示map的key类型,valueType表示map的value类型。size是一个整型参数,表示map的存储能力,该参数可省略。
1 2 3 4 5 6 7 | var m_ map [string]int = make( map [string]int) m_[ "one" ] = 1 fmt.Println(m_) var m map [string]int = map [string]int{ "1" :1} m[ "2" ] = 2 fmt.Println(m) |
根据 size 大小来初始化分配内存,不过分配后的 map 长度为 0,如果 size 被忽略了,那么会在初始化分配内存时分配一个小尺寸的内存
3、make 创建chanel
1 | make( chan Type, size) |
使用make创建channel,第一个参数是channel类型。size表示缓冲槽大小,是一个可选的大于或等于0的整型参数,默认size = 0。当缓冲槽不为0时,表示通道是一个异步通道。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package main import "fmt" func main() { demo := make( chan int, 10) fmt.Println( "demo:" , demo) // output: demo: map[] fmt.Println( "len(demo):" , len(demo)) // output: len(demo): 0 fmt.Println( "cap(demo):" , cap(demo)) // output: cap(demo): 10 } |
4、关于new函数
Go提供内建函数new
1 | func new(Type) *Type |
它只接受一个参数,这个参数是一个类型,分配好内存后,返回一个指向该类型内存地址的指针。同时请注意它同时把分配的内存置为零,也就是类型的零值。
1 2 3 4 5 6 | func main() { var i *int i=new(int) *i=10 fmt.Println(*i) } |
它返回的永远是类型的指针,指向分配类型的内存地址
5、注意事项 make和new的区别
-
new的作用是初始化一个指向类型的指针(*T)。使用new函数来分配空间,传递给new函数的是一个类型,不是一个值。返回的是指向这个新分配的零值的指针。(内存置为零)
-
make的作用是为slice、map或chan初始化并返回引用(T)。make仅仅用于创建slice、map和channel,并返回它们的实例。(非零值)
-
make返回的还是这三个引用类型本身;而new返回的是指向类型的指针
-
new不常用,通常都是采用短语句声明以及结构体的字面量达到我们的目的
-
make函数是无可替代的,二者都是内存的分配堆上
6、映射map
-
map是一种数据结构,用于存储一系列无序的键值对,类似java的HashMap
-
通过散列表实现,使用两个数据结构来存储数据,一个数组用于选择桶的散列键的高八位值,可以区分每个键值属于哪个桶;另一个字节数组,用于存储键值对
-
创建方式make(map[keyType] valueType, cap),其中keyType表示键类型,valueType表示值类型,cap表示初始存储能力
1 2 3 4 5 6 7 8 | //创建了一个键类型为string、值类型为PersonInfo myMap = make( map [string] PersonInfo) //也可以选择是否在创建时指定该map的初始存储能力,创建了一个初始存储能力为100的map. myMap = make( map [string] PersonInfo, 100) //创建并初始化map的代码. myMap = map [string] PersonInfo{ "1234" : PersonInfo{ "1" , "Jack" , "Room 101,..." }, } |
三、关于数组和切片的区别 ?
-
Slice和数组类似,也是表示一个有序元素,但这个序列的长度可变,具有动态长度特性;
-
切片是指针类型,数组是值类型;
-
数组的长度是固定的,而切片不是(切片可以看成动态的数组);
-
切片比数组多一个容量(cap)属性;
-
切片的底层是数组;
-
多个切片可以指向同一个底层数组,实现了内存共享
-
切片本身是一个只读对象,其工作机制类似数组指针的一种封装
以下代码输出什么?如果去掉注释又输出什么?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package main import ( "fmt" ) func main() { a := [2]int{5, 6} b := [2]int{5, 6} if a == b { fmt.Println( "equal" ) } else { fmt.Println( "not equal" ) } /* if a[:] == b[:] { fmt.Println("equal") } else { fmt.Println("not equal") } */ } |
输出:equal,去掉注释提示: invalid operation: a[:] == b[:] (slice can only be compared to nil)
go语言中数组和切片的区别
所以,a、b定义的是数组类型,数组对比是相同的,但是,a[:]、b[:]是切片,切片之间不能进行等值判断,只能和nil判断
- 作者:踏雪无痕
- 出处:http://www.cnblogs.com/chenpingzhao/
- 本文版权归作者和博客园共有,如需转载,请联系 pingzhao1990#163.com
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决
2019-05-30 【Linux】YUM Repositories for CentOS, RHEL & Fedora Systems