Go 语言基础之指针、复合类型【数组、切片、指针、map、struct】(2)https://developer.aliyun.com/article/1534258
4.2、map 的基本使用
4.2.1、添加元素
开辟内存空间之后,直接用就完了:
map[key] = value
4.2.2、初始化时添加元素
map 也支持初始化的时候指定元素(key 和 value 之间用引号而不是等号):
score := map[string]int{ "李大喜": 88, "燕双鹰": 99, } fmt.Println(len(score)) // 1 fmt.Println(score) // map[小明:98]
但是需要注意的是:初始化后的 map 不能再重新开辟内存了,否则会把初始化的内容全部清空!
但是初始化后的 map 默认是没有固定容量的,所以可以继续进行扩展。
4.2.3、判断 key 是否存在
判断方法:
value, ok := map[key]
返回两个值:第一个值是返回的该key对应的值,如果没有则为该值类型的初始值。第二个值为一个 bool 类型的值,表示状态(存在:true,不存在:false)。
users := map[string]int{ "李大喜": 88, "燕双鹰": 99, } value,status := users["谢永强"] if status{ fmt.Println("存在该用户并且value =",value) }else{ fmt.Println("不存在该用户") }
如果不希望得到状态值,可以使用 _ 进行忽略,或者:
value = users["谢永强"]
因为在Go语言中,range关键字用于遍历map时,会返回两个值,一个是键(key),另一个是值(value)。如果我们只使用了变量接收键,而没有使用任何变量来接收值,则编译器会自动忽略值的部分,只输出键。
4.2.4、map 的遍历
Go 语言使用 for range 来遍历 map:
users := map[string]int{ "李大喜": 88, "燕双鹰": 99, } users["谢永强"] = 95 for k,v := range users{ fmt.Println(k,v) }
可以看到,这一点 Go 语言做的要比 Java 简单很多很多!毕竟 Java 不支持返回多个返回值,除非封装成一个数组或者别的对象!
如果希望返回所有 value,可以这样:
delete(map, key)
for _,v := range users{ fmt.Println(v) }
4.2.5、使用 delete 函数删除键值对
使用delete()内建函数从map中删除一组键值对的格式如下:
delete(map, key)
注意:之所以叫内建函数,是因为 delete 函数是定义在 buildin.go 文件中的。
5、结构体
Go语言中没有“类”的概念,也不支持“类”的继承等面向对象的概念。Go语言中通过结构体的内嵌再配合接口比面向对象具有更高的扩展性和灵活性。Go 语言正是通过结构体来实现面向对象。
5.1、结构体的定义
type 类名 struct{ 字段名 字段类型 字段名 字段类型 //... }
比如:
type person struct { name string city string age int8 }
对于相同类型的字段可以写在一行:
type person struct { name city string age int8 }
5.2、结构体的实例化
和声明内置类型一样,我们可以使用 var 声明结构体类型:
var 结构体实例 结构体类型
比如:
type person struct { name string city string age int8 } func main(){ var p person p.name = "谢永强" p.city = "象牙山" p.age = 22 fmt.Println(p) // {谢永强 象牙山 22} fmt.Printf("%#v",p) // main.person{name:"谢永强", city:"象牙山", age:22} }
5.3、匿名结构体
在定义一些临时数据结构等场景下还可以使用匿名结构体:
func main(){ var p struct{name string;age int;city string} p.name = "谢永强" p.city = "象牙山" p.age = 22 fmt.Println(p) // {谢永强 象牙山 22} fmt.Printf("%#v",p) // struct { name string; age int; city string }{name:"谢永强", age:22, city:"象牙山"} }
5.4、结构体的初始化
5.4.1、使用键值对初始化
我们可以使用键值对的形式来实例化结构体:
type person struct{ name string age int8 city string } func main(){ p := person{ name :"谢永强", age : 22, city : "象牙山", } fmt.Printf("%#v",p) // main.person{name:"谢永强", age:22, city:"象牙山"} }
注意:没有初始化的结构体,其成员变量都是对应其类型的初始值。
5.4.2、使用列表进行初始化
使用列表进行初始化有以下这些要求:
- 必须初始化结构体的所有字段。
- 初始值的填充顺序必须与字段在结构体中的声明顺序一致。
type person struct{ name string age int8 city string } func main(){ p := person{ "谢永强", 22, "象牙山", } fmt.Printf("%#v",p) // main.person{name:"谢永强", age:22, city:"象牙山"} }
5.5、结构体内存布局
结构体占用一块连续的内存。
type test struct { a int8 b int8 c int8 d int8 } func main(){ n := test{ 1, 2, 3, 4, } fmt.Printf("n.a %p\n", &n.a) fmt.Printf("n.b %p\n", &n.b) fmt.Printf("n.c %p\n", &n.c) fmt.Printf("n.d %p\n", &n.d) }
运行结果:
n.a 0xc000014028 n.b 0xc000014029 n.c 0xc00001402a n.d 0xc00001402b
注意:空结构体是不占用空间的。
5.6、构造函数
Go语言的结构体没有构造函数,但是我们可以自己实现:
type person struct{ name string age int8 city string } func newPerson(name,city string,age int8) *person{ return &person{ name : name, city : city, age : age, } } func main(){ p := newPerson("张三","北京",22) fmt.Printf("%#v\n", p) // &main.person{name:"张三", age:22, city:"北京"} }
5.7、方法与接受者
Go语言中的方法是一种作用于特定类型变量的函数。这种特定类型变量叫做接收者。接收者的概念就类似于 Java 中的 this 。
方法与函数的区别是,函数不属于任何类型,方法属于特定的类型。
5.7.1、创建方法
func (接收者变量 接收者类型) 方法名(参数列表) (返回参数) { 函数体 }
- 接收者变量:在命名时,官方建议使用接受者类型名称首字母小写
- 接收者类型:可以是指针类型和非指针类型
type person struct{ name string age int8 city string } // 构造器 func newPerson(name,city string,age int8) *person{ return &person{ name : name, city : city, age : age, } } // person 的方法 func (p person) eat(){ fmt.Println("人会吃饭") } func main(){ p := newPerson("张三","北京",22) p.eat() // 人会吃饭 fmt.Printf("%#v\n", p) // &main.person{name:"张三", age:22, city:"北京"} }
Go 语言基础之指针、复合类型【数组、切片、指针、map、struct】(4)https://developer.aliyun.com/article/1534261