map的基本介绍
map是key-value数据结构,又称为字段或者关联数组。类似其它编程语言的集合。
map的声明
基本语法
var map变量名 map[keytype]valuetype
案例: var a map[string]int
map的声明是不会分配内存的,初始化需要make,分配内存后才能赋值和使用。
注意事项:
1)map在使用前一定要make。
2)map的key是不能重复,如果重复了,则以最后这个key-value为准。
3)map的value是可以相同的。
4)map的key-value是无序。
5)map内置函数数目 a =make(map[string]string,10)
//map使用的第一种方式
var a map[string]string
//在使用map前,需要先make(),make()的作用就是给map分配空间
a = make(map[string]string,10)
a["name1"] = "张三"
a["name2"] = "李四"
a["name3"] = "王五"
//map使用的第二种方式
cities := make(map[string]string)
cities["city1"] = "北京"
cities["city2"] = "上海"
cities["city3"] = "武汉"
//map使用的第三种方式
heroes := map[string]string{
"name1" : "张三",
"name2" : "李四",
"name3" : "王五",
}
heroes["name4"] = "马子"
map的增删改查操作
map增加和更新
//如果key还没有,就是增加,如果key存在就是修改
map[“key”] = value
map删除
delete(map,“key”) ,delete是一个内置函数,如果key存在,就删除该key-value,如果key不存在,不操作也不会报错。
//内建函数delete按照指定的键将元素从映射中删除。若m为nil或无此元素,delete不进行操作。
func delete(m map[Type]Type1, key Type)
如果我们要删除map的所有key,没有一个专门的方法一次删除,可以遍历一下key,来逐个删除 或map = make(…),make一个新的,让原来的成为垃圾,被gc回收。
map查询
val , ok :=cities["name1"]
if ok {
fmt.Printf("存在name1 值为%v",val)
}else {
fmt.Printf("没有key为name1的值")
}
map的使用注意事项和细节
1)map是引用类型,遵守引用类型传递的机制,在一个函数接受map,修改后会直接修改原来的map。
2)map的容量达到后,在想map增加元素,会自动扩容,并不会发生panic,也就是说map能动态的增长。
3)map是value也经常使用struct类型,更适合管理复杂的数据。
结构体
如何声明结构体
type 结构体名称 struct{
field1 type
field2 type
}
type Student struct{
Namr string
Age int
Score float64
}
创建结构体
type Person struct{
Name string
Age int
}
//方式1 直接声明
var person Person
person.Name = "marg"
person.Age = 20
//方式2
var person Person =Person {"mary",20}
//方式3
// var person * Person = new(Person)
var person *Person = new(Person)
//因为person是一个指针,因此标准的给字段赋值方式
// (*person).Name = "mary" 也可以这样写 person.Name = "mary"
//原因 :go的设计者 为了程序员使用方便 ,底层对 person.Name = "mary"进行了处理
// 会给person加上取值运算(*person).Name = "mary"
(*person).Name = "mary"
person.Name = "jack"
//方式4
//var person *Person = &Person{}
var person *Person = &Person{"mary",20}
说明:
1)第三种和第四种方式返回的是 结构体指针
2)结构体指针访问字段的标准方式应该是:(*结构体指针).字段名,比如(*person).Name = “tom”
3)但go设计者做了一个简化,也支持 结构体指针.字段名。go编译器底层对person.Name 做了转化(*person).Name
结构体使用主要事项和细节
1)结构体的所有字段在内存中是连续的
2)结构体是用户单独定义的类型,和其它类型进行转换时需要有完全相同的字段(名字,个数和类型)
type A struct {
Num int
}
type B struct {
Num int
}
fun main() {
var a A
var b B
a = A(b)
}
3)结构体进行type重新定义(相等于取别名),Golang认为是新的数据类型,但是相互间可以强转
4) struct的每个字段上,可以写一个tag,该tag可以通过发射机制获取。
type Monster struct{
Name string `json:"name"`
Age int `json:"age"`
}