• 【golang学习笔记2.2】 Map、结构体和接口


    Map的基本介绍

    map是一个key-value的数据结构;类似于其他编程语言中的集合
    基本语法和注意事项

    1. var map 变量名 map[keytype]valuetype
    2. keytype的类型有很多种比如bool,string,指针 ,管道,接口,结构体,数组等
    3. keytype通常为int,string,slice,map,function不可以,因为这几个没法用==来进行判断
    4. valuetype的类型和keytype差不多。通常为数字类型【int ,float】,stiring,结构体
    5. map的声明不会分配内存,初始化需要make,分配内存后才可以赋值使用

    map的声明和简单使用

    package main
    
    import (
    	"fmt"
    )
    func main() {
    	//第一种 先声明 在初始化
    	var mapp map[string]string
    	//这样赋值会报错,因为没有给分配内存空间
    	//mapp["n1"]="张三“
    	mapp = make(map[string]string)
    	mapp["n1"] = "张三"
    	mapp["n2"] = "李四"
    	mapp["n3"] = "王武"
    	mapp["n1"] = "开心"
    	mapp["n4"] = "乐哈哈"
    	//打印结果 mapp: map[n1:开心 n2:李四 n3:王武 n4:乐哈哈]
    	fmt.Printf("mapp: %v\n", mapp)
    	//第二种 直接进行初始化
    	var mapas = make(map[string]string)
    	mapas["n1"] = "张三"
    	fmt.Printf("mapas: %v\n", mapas)
    	//第三种 直接赋值
    	var maps = map[int]string{
    		0: "张三",
    		1: "李四",
    		2: "王武",
    	}
    	fmt.Printf("maps: %v\n", maps)
    }
    
    • 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

    map的增删改查

    package main
    import (
    	"fmt"
    )
    func main() { 
    	var mapas = make(map[string]string)
    	//没有就是增加,存在就是修改
    	mapas["n1"] = "张三"
    	mapas["n2"] = "李四"
    	mapas["n3"] = "王五"
    	mapas["n1"] = "赵六"
    	fmt.Printf("mapas: %v\n", mapas)
    	//单个删除 delect 内置函数,删除map里面的指定key【键名】,如果存在就删除,不存在也不执行,不会报错
    	delete(mapas,"n1")
    	//批量删除【清空map】;重新进行初始化,原来的会被go的垃圾回收机制回收
    	mapas=make(map[string]string)
    	fmt.Printf("mapas: %v\n", mapas)
    	//查找指定的mapkey;会返回值和一个bool;为true时存在为fasle不存在
    	val,boola:=mapas["n2"]
    	if boola{
    		fmt.Printf("val: %v\n", val)
    	}else{
    		 fmt.Printf("err: %v\n", boola)
    	}
    }
    
    
    • 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

    map的遍历

    map只能使用for-range循环

    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    
    	var mapas = make(map[string]string)
    	mapas["n1"] = "张三"
    	mapas["n2"] = "李四"
    	mapas["n3"] = "王五"
    	mapas["n4"] = "赵六"
    	for k, v := range mapas {
    		fmt.Printf("k: %v v: %v\n", k, v)
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    map切片【动态添加切片】

    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	//map第一种 先声明分配一些内存
    	var mapas= make([]map[string]string,2)
    	   //声明固定内存
    	   mapas[0]=make(map[string]string,2)
    	   mapas[0]["age"]="20"
    	   mapas[0]["name"]="张三"
    	   //默认分配
    	   mapas[1]=make(map[string]string)
    	   mapas[1]["age"]="30"
    	   mapas[1]["name"]="李四"
    
    	   newName:=map[string]string{
    		  "age":"40",
    		  "name":"王五",
    	   }
    	   //在使用append()方法进行动态添加
    	   mapas=append(mapas, newName)
    	   fmt.Printf("mapas: %v\n", mapas) 
    	 //第二种  声明一个map切片;然后直接使用append方法追加
    	 var mapas2 []map[string]string
    	   newName2:=map[string]string{
    		  "age":"40",
    		  "name":"王五",
    	   }
    	   //在使用append()方法进行动态添加
    	   mapas2=append(mapas2, newName2)
    	   fmt.Printf("mapas2: %v\n", mapas2) 
    }
    
    
    • 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

    map使用的细节

    1. map是引用类型,遵守引用类型传递的机制,在一个函数接受map,会修改原来的map
    2. map的容量到达到后,map会自动扩容,也就是说map是动态增长的key-value键值对
    package main
    
    import (
    	"fmt"
    )
    
    func num(map1 map[int]int){
    	     map1[2]=10000
    }
    
    func main() {
        map1:=make(map[int]int)
    	map1[10]=10
    	map1[2]=20
    	map1[4]=1110
    	map1[7]=130
    	map1[8]=145
    	map1[1]=121
    	num(map1)
    	//打印结果 map1: map[1:121 2:10000 4:1110 7:130 8:145 10:10]
    	//这里的map[2]就被函数直接修改了,所以说明map是引用类型 
    	fmt.Printf("map1: %v\n", map1)
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    结构体

    结构体是自定义的数据类型,代表一类事物。
    结构体变量是具体的,代表一个具体的变量。
    我这里理解的是把结构体当作php中的类来看 好容易理解一些
    案例1:

    package main
    
    import (
    	"fmt"
    )
    
    //声明一个结构体
    type Person struct {
    	//Name 可以理解为字段
    	//string 可以理解为这个字段的属性
    	// `json:"skin"` tag 返回数据格式和名称
    	Name   string  `json:"name"`
    	Age    int
    	Scores [2]float64
    	Ptr    *int
    	Slice  []int
    	map1   map[int]int
    	boola  bool
    }
    
    func main() {
    
    	var person Person
    	//如果没有给结构体默认值,那么结构体会返回对应类型的初始值
    	//并且有些是没有分配内存是无法直接使用的,比如结构体 如果不先make那么无法直接对其进行赋值
    	//打印结果 person: { 0 [0 0]  [] map[] false}
    	fmt.Printf("person: %v\n", person)
    
    }
    
    • 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

    案例2:

    package main
    
    import (
    	"fmt"
    )
    //声明一个结构体
    type test struct {
    	name string 
    	age  int 
    	fenshu int 
    }
    func main() {
    	//声明一个结构体,并初始化;注意name不需要加""
    	 var test2 =test{
    		 name:"张三",
    		 age:20,
    		 fenshu:100,
    	}
    	fmt.Printf("test2.name: %v\n", test2.name)
    	fmt.Printf("test2.age: %v\n", test2.age)
    	fmt.Printf("test2.fenshu: %v\n", test2.fenshu)
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    1. 结构体的创建的几种方式
    package main
    
    import (
    	"fmt"
    )
    
    //声明一个结构体
    type Person struct {
    	//Name 可以理解为字段
    	//string 可以理解为这个字段的属性
    	// `json:"skin"` tag 返回数据格式和名称
    	Name   string  `json:"name"`
    	Age    int
    	Scores [2]float64
    	Ptr    *int
    	Slice  []int
    	map1   map[int]int
    	boola  bool
    }
    
    func main() {
        
    	//第一种 
    	var p1 Person
    	//打印结果 person: { 0 [0 0]  [] map[] false}
    	fmt.Printf("p1: %v\n", p1)
        //第二种
    	p2:=Person{}
    	p2.Name="张三"
    	//打印结果 p2: {张三 0 [0 0]  [] map[] false}  
    	fmt.Printf("p2: %v\n", p2)
    	//第三种;new 会生成一个指针
    	p3:=new (Person)
    	p3.Name="李四"
    	p3.Age=20
    	//打印结果 p3: &{李四 20 [0 0]  [] map[] false}
    	fmt.Printf("p3: %v\n", p3)
    	//第四种也会生成一个指针类型
    	var p4 *Person=&Person{}
    	p4.Name="王五"
    	//打印结果 p4: &{王五 0 [0 0]  [] map[] false}
    	fmt.Printf("p4: %v\n", p4)
    }
     
    
    • 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

    方法的声明(定义)

    基本结构
    func(名称 类型)方法名(参数列表【参数 类型,参数 类型…】)(返回值列表【返回值 类型,返回值 类型…】){
    代码…
    //return和返回值列表不是一定需要的;
    return 返回值
    }
    案例1:

    package main
    
    import (
    	"fmt"
    )
    
    //声明一个结构体
    type Person struct {
    	Name   string  `json:"name"`
    	Age    int
    	Scores [2]float64
    	Ptr    *int
    	Slice  []int
    	map1   map[int]int
    	boola  bool
    }
    //给Person绑定一个方法
    func(p Person) test(){
        p.Name="张三"
    	fmt.Printf("p: %v\n", p)
    }
    func(p *Person)test2(){
    	 p.Name="赵六"
    	 fmt.Printf("p: %v\n", p) 
    } 
    func main() {
    	//第一种 
    	var p1 Person
    	p1.Name="李四"
    	//调用方法
    	//打印结果 p: {张三 0 [0 0]  [] map[] false} 
        p1.test()
    	//打印结果 p1: {李四 0 [0 0]  [] map[] false}
    	fmt.Printf("p1: %v\n", p1)
        //总结
    	//调用方法并不会改变方法外的值。
    	//这种方法为值传递;是值拷贝的传递方式。不是引用类型
    	//如果想调用方法改变外面的值;那么方法里面使用指针类型即可
    	p2:=new (Person)
    	p2.Name="张三"
    	//打印结果 p: &{赵六 0 [0 0]  [] map[] false} 
    	p2.test2()
    	//打印结果 p2: &{赵六 0 [0 0]  [] map[] false}
    	fmt.Printf("p2: %v\n", p2)
    }
    
    • 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

    案例2:

    package main
    
    import (
    	"fmt"
    )
    
    //声明一个结构体
    type Person struct {
    	Name   string  `json:"name"`
    	Age    int
    	Scores [2]float64
    	Ptr    *int
    	Slice  []int
    	map1   map[int]int
    	boola  bool
    }
    //给Person绑定一个方法
    func(p Person) test(num int)int{
        p.Name="张三"
    	fmt.Printf("p: %v\n", p)
    	num=num+1 
    	return num
    }
     
    func main() {
    	 
    	var p1 Person
    	num:=p1.test(2)
        fmt.Printf("num: %v\n", num)
    }
    
    • 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

    接口的定义

    接口类型可以定义一组方法,不需要实现,接口里面不能包含任意变量,在定义结构体的时候 在具体实现方法

    package main
    
    import (
    	"fmt"
    )
    //定义一个接口,接口里面有一个跳转不同页面的方法
    type Home interface {
    	HomeIndex()
    }
    //定义新闻首页的结构体
    type NewList struct {
    }
    
    //定义调用新闻首页的方法
    func (new NewList) HomeIndex() {
    	fmt.Printf("新闻首页")
    }
    //定义一个新闻首页独有的方法
    func (new NewList)Banner(){
        fmt.Printf("新闻轮播图")
    }
    //定义店铺首页的结构体
    type ShopHome struct {
    }
    
    //定义调用店铺首页的方法
    func (shop ShopHome) HomeIndex() {
    	fmt.Printf("店铺首页")
    }
    
    //声明一个进入的初始化结构体
    type Index struct {
    }
    
    //定义一个引用接口为参数的方法;里面是调用接口里面的方法
    func (index Index) Index(home Home) {
    	home.HomeIndex()
    	//类型断言;判断是否调用不同的结构体方法
    	if NewList,ok:=home.(NewList);ok{
             NewList.Banner()  
    	}
    }
    
    func main() {
    	//创建结构体
    	new := NewList{}
    	shop := ShopHome{}
    	index := Index{}
    	//调用方法;方法里面是引用的接口
    	//打印结果是 新闻首页
    	index.Index(new)
    	fmt.Println()
    	//打印结果是 店铺首页
    	index.Index(shop)
    }
    
    • 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
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
  • 相关阅读:
    我叫:选择排序【JAVA】
    Leetcode刷题详解——二分查找
    激活函数总结(三十三):激活函数补充(QReLU、m-QReLU)
    Tomcat部署及优化
    二进制部署1.23.4版本k8s集群-5-部署Master节点服务
    XGboost遥感gis数据的回归预测(复合结果预测, 多列预测)实践(python版)
    TCP/IP 协议
    高速DSP系统设计参考指南(一)高速DSP设计面临的挑战
    Stokes‘ theorem
    正则表达式:字符(2)
  • 原文地址:https://blog.csdn.net/weixin_44779466/article/details/125995855