GO基础,数组、切片、Map、函数

数组:

定义:

  方式一:

arr1 := [...]int{1,2,3} 

  方式二: arr2 := [3]int{1,2,3}

  方式三: var arr3 [3]int

遍历:

//遍历数组
        for k, v :=range arr3{
                fmt.Println("key:%v,value:$v",k,v)
        }

 

值类型和引用类型:

1.基本数据类型 和 数组 都为值类型

2.改变副本值会影响原来值的为引用数据类型 指向的为同一个内存地址 。包含(切片)

定义二维数组:

    //定义二维数组
        arr := [3][2]string{
                {"北京","上海"},
                {"武汉","长沙"},
                {"南昌","成都"},
        }
        //遍历
        for _,v1 :=range arr{
                for _,v2 := range v1 {
                        println(v2)
                }
        }
                

  

切片


切片的本质就是对底层数组的封装 ,类似可变长度数组 声明未复制 默认值为 nil
len(s)获取长度, cap(s)获取容量
长度:所含元素个数
容量:从第一个元素开始数,到底层数组末尾的个数
append()为切片动态添加元素,长度和容量同时会增加
合并切片
        sliceA := []string{"张三丰","张学友","张国荣"}
        sliceB := []string{"刘德华","谢霆锋","阿三"}
        sliceA = append(sliceA,sliceB...)
        fmt.Println(sliceA)

 copy()复制切片 防止改变副本而改变本身

        sliceA := []string{"张三丰","张学友","张国荣"}
        sliceB := make([]string,4,4)
        //sliceC := []string{"刘德华","谢霆锋","阿三"}
        //sliceA = append(sliceA,sliceB...,sliceC...)
        copy(sliceB,sliceA) //把sliceA拷贝给sliceB中
        fmt.Println(sliceB) 

 删除切片元素

  用append方法删除

字符串 切片的互换

       //字符串转切片
        s1 := "你好 golang"
        runeStr := []rune(s1)
        runeStr[0] = '您'
        fmt.Println(string(runeStr))

  

Map
是无序的k-v数据结构 为引用类型 必须初始化 默认值为nil
       //方式一
        var userinfo = make(map[string]string) //创建集合 第一个string为key的类型  第二个string为值的类型
        userinfo["title"] = "111"
        fmt.Println(userinfo)
        //方式二
        userdata := map[string]string{
                "ID":"1",
                "title":"测试标题",
        }
        fmt.Println(userdata)判断

判断某个key是否存在

v,ok := userdata["title"] //如果存在 v就是值 ok就为true  不存在 v就是空 ok就为false删除

删除key

delete(userdata, "title") //userData为map  title为key创建

创建一个Map类型的切片

       //创建一个元素为map类型的切片
        var userinfo = make([]map[string]string,3,3)
        if(userinfo[0] == nil){
                userinfo[0] = make(map[string]string)
                userinfo[0]["title"] = "测试标题"
        }
        fmt.Println(userinfo)值

值为切片类型的Map对象

      //创建一个值为切片的map
        var userinfo = make(map[string][]string)
        userinfo["hobby"] = []string{
                "吃饭","睡觉",
        }
        fmt.Println(userinfo) 

函数

定义多参数的函数

//函数
func sumFn1(x ...int){ //不固定参数
        fmt.Println(x)
}

//调用
sumFn1(1,2,3,4,5)

自定义函数类型

type calc func(x,y int) int  //定义个calc类型的函数

func add(x ,y int) int{
        return x + y
}


func main(){
        var c calc
        c = add  //add必须和C类型一致
        fmt.Printf("c的类型%T",c)
        //调用
        d := c(2,7)
        fmt.Println(d)
} 

 函数递归

func fnDg(n int) int{
        if n > 1{
                return n + fnDg(n-1)
        }else{
                return 1
        }
}

func main(){
        //函数递归
        sum := fnDg(100) //计算1-100的和
        fmt.Println(sum)

} 

 闭包

func add(x int) func() int{
        return func() int {
                return x+1
        }
}

func main(){
        //闭包函数 -- 全局变量会常驻内存,污染全局 ,闭包可以让一个变量常驻内存并不会污染全局
        //闭包是指有权访问另一个函数作用域中变量的函数
        //注意事项:由于闭包里局部变量资源不会立即销毁,所以可能会占用更多的内存
        var fn = add(2)() //返回的是一个函数 执行的话需带()
        fmt.Println(fn)

defer

//defer语句 -- 会将其后面跟随的语句延时处理 defer所属函数即将返回时 将延时语句逆向执行 (先被defer的语句最后执行 后被defer的语句先执行)
        defer fmt.Println("111")
        defer fmt.Println("222")
        defer fmt.Println("333")
        defer fmt.Println("444")

        //匿名返回值和命名返回值
        //匿名返回值不影响
        //命名返回值是执行之后的值

panic和recover

//panic在任何地方都可以触发  recover监听panic的异常 只有在defer调用的函数中有效
func fn1(){
        defer func() {
                err := recover()
                if err != nil {
                        fmt.Println(err)
                }
        }()
        panic("发现异常")
}
//make和new内存分配 (new主要针对指针类型 make主要用于map、切片和channel)