青训营后端Go语言基础(二) | 豆包MarsCode AI 刷题

20 阅读8分钟

6.go语言的 break continue 关键字

break的使用

break语句可以结束forswitchselect的代码块。

1.单独在select中使用break和不使用break没有啥区别。

2.单独在表达式switch语句,并且没有fallthrough,使用break和不使用break没有啥区别。

3.单独在表达式switch语句,并且有fallthrough,使用break能够终止fallthrough后面的case语句的执行。

4.带标签的break可以跳出多层select/switch作用域。让break更加灵活,写法更加简单灵活,不需要使用控制变量一层一层跳出循环,没有带break的只能跳出

//特例:跳转到标签处
func main(){
MY_LABEL:
    for i := 0; i < 5; i++ {
        if i == 3 {
            break MY_LABEL
        }
        fmt.Printf("%v\n", i)
    }
    fmt.Println("end...")
}

continue的使用

continue只能用在循环中,在go中只能用在for循环中,它可以终止本次循环,进行下一次循环。

continue语句后添加标签时,表示开始标签对应的循环

//特例跳转到标签
func main(){
    MY_LABEL:
    for i:=0;i<5;i++{
        if i==3{
            continue MY_LABEL
        }
        fmt.Printf("%v\n",i)
    }
    fmt.Println("end...")
}

7.数组

go语言中的数组是相同数据类型的一组数据的集合,数组一旦定义长度不能修改,数组可以通过下标(或者叫索引) 来访问元素

数组不能用make()函数来声明初始化

go语言数组的定义

var 数组名称 [数组长度,必须是常量] 数组保存元素的类型
//eg:
var arr [3] int//初始化
arr = [3]int{1, 2, 3}//初始化在赋值法
for k, v := range arr {
    fmt.Println(k, v)
}

go语言数组的初始化

初始化,就是给数组的元素赋值,没有初始化的数组,默认元素值都是零值,布尔类型是false,字符串是空字符串

go
 代码解读
复制代码
//1.使用初始化列表
    var a = [3]int{1,2,3}
    var s = [2]string{"小明","小刘"}
    var b = [2]bool{true,false}
//2.使用初始化列表(类型推断法)
    a:=[3]int{1,2}
    s:=[2]string{"小明","小刘"}
    b:=[2]bool{true,false}
//3.省略数组长度 数组长度可以省略,使用...代替,初始化值得数量自动判断
    var a = [...]int{1,2,3}
    var s = [...]string{"小明","小刘"}
    var b = [...]bool{true,false}
    a2: = [...]int{1,2,3}
//4.指定索引值的方式来初始化 可以通过指定所有的方式来初始化,未指定的int,float默认为零值,布尔为false string为空字符串
    a:=[...]int{0:1,2:3}
    s:=[...]string{0:"小明",2:"小刘"}
    b:=[...]bool{0:true,2:false}
}

go语言访问数组元素

可以通过下标的方式,来访问数组元素。数组的最大下标为数组长度-1,大于这个下标会发生数组越界

func main{
    var arr=[...]int{1,2,3}
    fmt.Println(arr[0])//对
    fmt.Println(arr[3])//越界
    //修改arr[0] arr[1]
    arr[0]=4
    arr[1]=5
}

根据数组长度遍历数组

可以根据数组长度,通过for循环和for range循环的方式来遍历数组,数组的长度可以用lengo语言中内置函数来获得

//1.for循环
func main{
    a := [...]string{"小明", "小刘", "小张"}
    for i := 0; i < len(a); i++ {
        fmt.Printf("下标:%v 值:%v", i, a[i])
    }
}
//2.for range循环
func main(){
    var arr = [...]bool{true, false, true, false}
    for i, v := range arr {
        fmt.Printf("下标为:%v,值为:%v", i, v)
    } 
}

多维(二维)数组

多维数组中的每一个元素又是一个数组

//二维数组的定义
var arrs[][]string

//1.初始化写法
var arrs=[][]string{
    {"小A","小B"},
    {"小C","小D"},
    {"小E","小F"},
}
//2.初始化写法
arrs:=[...][]string{
    {"小A","小B"},
    {"小C","小D"},
    {"小E","小F"},
}
//3.不支持写法
arrs:=[][...]string{
    {"小A","小B},
    {"小C","小D"},
    {"小E","小F"},
}
//1.二维数组的遍历方法1 for循环
func main(){
    var arr = [...][]int{
        {1, 2},
        {3, 4},
        {5, 6},
    }
    for _, v1 := range arr {
        for _, v2 := range v1 {
            fmt.Printf("值:%v", v2)
        }
    }
}
//2.二维数组的遍历方法2 for range循环
func main(){
    var arr = [...][]int{
        {1, 2},
        {3, 4},
        {5, 6},
    }
    for i := 0; i < len(arr); i++ {
        for j := 0; j < len(arr[i]); j++ {
            fmt.Print(arr[i][j])
        }
        fmt.Println()
    }
}

8.切片

1.前面我们学习了数组,数组是固定长度,可以容纳相同数据类型的元素的集合。当长度固定时,使用还是带来一些

限制,比如:我们申请的长度太大浪费内存,大小又不够用

2.鉴于上述原因,我们有了go语言的切片,可以把切片理解为,可变长度的数组,其实它底层就是用数组实现的,增加

了自动扩容功能。切片(slice)是一个拥有相同类型元素的可变长度的序列

3.map引用类型

切片相关的语法

声明一个切片和声明一个数组类似,只要不添加长度就可以了

var sli [] int

切片的正常初始化

var sli = []int{1,2,3}

切片是引用类型,可以用make函数来创建切片:


var sli = make([]int,len)
还可以简写为
sli:=make([]int,len)

也可以指定容量,其中capacity为可选参数

make([]int,len,cap)

这里的len是数组的长度且也是切片的初始长度

切片的长度和容量

切片拥有自己的长度和容量,我们可以通过使用内置的len()函数求长度,使用内置的cap()函数求切片的容量

var names = []string{"小A", "小B"}
var num = []int{1, 2, 3}
fmt.Printf("len:%d cap:%d\n", len(names), cap(names))
fmt.Printf("len:%d cap:%d\n", len(num), cap(num))
var s []int = make([]int, 2, 3)
var s1 = make([]string, 3, 4)
fmt.Printf("len:%d cap:%d\n", len(s), cap(s))
fmt.Printf("len:%d cap:%d\n", len(s1), cap(s1))

切片的初始化

切片的初始化方法很多,可以直接初始化,也可以使用数组初始化等

直接初始化

s := []int{1, 2, 3}
    fmt.Println(s)

使用数组初始化

arr := [...]int{1, 2, 3}
    s1 := arr[:]
    fmt.Println(s1)

使用数组的部分元素初始化(切片表达式)

切片的底层就是一个数组, 所以我们可以基于数组通过切片表达式得到切片。切片表达式中的low和high表示一个

索引范围 (左包含,右不包含) ,得到的切片长度=high-low,容量等于得到的切片的起始位置开始到切片长度

注意:数组和切片都可以这样划分得到新数组或者新切片

arr := [...]int{1, 2, 3, 4, 5, 6}
s1 := arr[:]                      //[]
fmt.Println(s1, len(s1), cap(s1)) //1,2,3,4,5,6 len6 cap6
s2 := arr[2:5]                    //[)
fmt.Println(s2, len(s2), cap(s2)) //3,4,5 len3 cap4
s3 := arr[:3]                     //[)
fmt.Println(s3, len(s3), cap(s3)) //1,2,3 len3 cap6
s4 := arr[2:]                     //2]
fmt.Println(s4, len(s4), cap(s4)) //3,4,5,6 len4 cap4

空(nil)切片

一个切片在未初始化之前默认为nil,长度为0,容量为0

var s1 []int
fmt.Println(s1==nil)//true
fmt.Printf("len:%d,cap:%d\n",len(s1),cap(s1))//0,0

切片的遍历

两种方式:forfor range

//1.for
s1 := []int{1, 2, 3, 4, 5, 6}
    for i := 0; i < len(s1); i++ {
        fmt.Println(s1[i])
    }
//2.for range
s1 := []int{1, 2, 3, 4, 5, 6}
for i, v := range s1 {
        fmt.Println(i, v)
    }

切片的增删改查和copy

切片是一个动态数组,可以使用append()函数添加元素,go语言中没有删除切片元素的专用方法,我们可以使用切片本身的特性来删除* 元素 。由于,切片是引用类型,通过赋值的方式,会修改原有的内容,go提供了copy()函数来拷贝切片( 但必须要用make()函数来创建切片) *

append()函数扩容后再赋值的数组或者切片是新切片和新数组

//1.单个增加
var sliceA []int
sliceA = append(sliceA, 12)
fmt.Println(sliceA) //12
sliceA = append(sliceA, 24)
fmt.Println(sliceA) //12,24
//2.
var sliceA = []int{1, 2, 3}
sliceA = append(sliceA, 4, 5, 6, 7, 8, 9, 10)
fmt.Println(sliceA)//1,2,3,4,5,6,7,8,9,10
//3.
var sliceA = make([]int, 3, 4)
sliceA = append(sliceA, 1, 2, 3)
fmt.Println(sliceA)//0 0 0 1 2 3
//4.多个增加
var sliceB []int
sliceB= append(sliceB,12,24,36,48,60)
fmt.Println(sliceB)//12,24,36,48,60
//5.append()函数实现两个切片之间的合并 即 把一个切片合并到另一个切片里并形成一个新的切片
sliceA := []string{"小A", "爱MarsCode"}
sliceB := []string{"小B", "爱字节"}
var sliceC []string
sliceC = append(sliceA, sliceB...)//...固定语法
fmt.Println(sliceC)

go语言中并没有删除切片的元素的专用方法,我们可以使用切片本身的特性来删除元素

sliceA := []int{1, 2, 3, 4, 5, 6}
//要删除索引为2的元素
sliceA = append(sliceA[:2], sliceA[3:]...)
fmt.Println(sliceA)//1 2 4 5 6

//正确写法(make)    指定长度 没有越界
var s1 = make([]int, 4, 8)
    s1[0] = 10
    s1[1] = 11
    s1[2] = 12
    s1[3] = 13
    fmt.Println(s1)
//正确写法(正常)    指定长度 没有越界
var s1 = []int{1,2}
    s1[0]=2
    s1[1]=3
    fmt.Println(s1)
//错误写法 长度不够 越界了
var s1 = []int{1, 2}
    s1[0] = 10
    s1[1] = 11
    s1[2] = 12
    s1[3] = 13
    fmt.Println(s1)

var s1 = []int{1, 2, 3, 4}
    fmt.Println(s1[0])
    fmt.Println(s1[1])
    fmt.Println(s1[2])
    fmt.Println(s1[3])

copy

copy()内置函数

sliceA := []int{1, 2, 3}
sliceB := make([]int, 3, 3)
copy(sliceB, sliceA) //右边复制给左边
sliceB[0] = 4
fmt.Println(sliceA)//1 2 3
fmt.Println(sliceB)//4 2 3

今天就写到里了,欢迎大家指正!