• 数组切片和函数


    数据的声明

    // 数据是存放元素的容器
    // 必须指定存放的元素的类型和容量(长度)
    // 数组的长度是数组类型的一部分
    var a1 [3]bool // [false false false]
    var a2 [4]bool // [false false false false]
    fmt.Prinf("a1:%V a2:%V
    ",a1,a1)
    

    数组的初始化

    // 数组的初始化
    // 如果不初始化:默认元素都是零值(布尔值:false,整型和浮点型都是0,字符串:"")
    fmt.Println(a1,a2)
    // 1.初始化方法1
    a1 = [3]bool{true,true,ture}
    fmt.Println(a1)
    // 2. 初始化方式2:根据初始值自动推算数组的长度是多少
    // a10 :=[9]int{0,1,2,3,4,5,5,6,7}
    a10 := [...]int{1,2,3,4,5,5,6}
    fmt.Println(a10)
    // 3初始化方式3;根据索引来初始化
    a2 := [5]int{0:1,4:2}
    fmt.Println(a3)
    

    数据的遍历

    // 数组的遍历
    citys := [...]string{"北京","上海","深圳"} 
    // 索引:0~2 citys[0],citys[1],citys[1]
    // 1 根据索引遍历
    for i:=0; i< len(citys); i++ {
        fmt.Println(citys[i])
    }
    // 2 for range遍历
    for i,v := range citys{
        fmt.Println(i,v)
    }
    

    数据是值类型

    // 数组是值类型
    b1 := [3]int{1,2,3} // [1 2 3]
    b2 := b1            // [1 2 3]
    b2[0] = 100         //b2:[100 2 3]
    fmt.Println(b1,b2)  // b1:[1 2 3]
    

    切片(slice)

    切片只想了一个底层的数组
    切片的长度就是它元素的个数
    切片的容量是底层数组从切片的第一个元素到最后一个元素

    切片的定义

    // 切片的定义
    var s1 [] int // 定义一个存放int类型元素的切片
    var s2 [] string // 定义一个存放string类型元素的切片
    fmt.Println(s1,s2)
    fmt.Println(s1 == nil) // true
    fmt.Println(s2 == nil) // true
    

    切片的初始化

    // 初始化
    s1 := []int{1,2,3}
    s2 := []string{"沙河","松兰堡"}
    fmt.Println(s1,s2)
    fmt.Println(s1 == nil) // false
    fmt.Println(s2 == nil) // false
    

    切片的长度和容量

    // 长度和容量
    fmt.Printf("len(s1):%d cap(s1):%d",len(s1),cap(s1))
    fmt.Printf("len(s2):%d cap(s2):%d",len(s2),cap(s2))
    

    make

    make()函数用于创建指定长度和容量的切片

    s1 := make([]int,5,10)
    fmt.Printf("len(s1):%d cap(s1):%d",len(s1),cap(s1))
    
    s2 := make([]int,0,10)
    fmt.Printf("len(s2):%d cap(s2):%d",len(s2),cap(s2))
    

    切片的本质

    切片就是一个框,框住了一片连续的内存
    切片属于引用类型,真正的数据都是保存在底层的数组里面
    判断一个切片是否是空,要使用len(s)==0来判断

    append

    
    // 调用append函数必须使用原来的切片变量接收返回值
    // append追加元素,原来的底层数组放不下的时候,go底层就会把底层数组换一个
    //  必须用变量接收append的返回值
    s1 = append(s1,"广州")
    fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d
    ",s1,len(s1),cap(s1))
    s1 = append(s1,"杭州","成都")
    fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d
    ",s1,len(s1),cap(s1))
    
    ss := []string{"武汉","西安"}
    s1 = append(s1,ss...) // ... 标识可以拆开
    fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d
    ",s1,len(s1),cap(s1))
    

    copy

    a1 :=  []int{1,3,5}
    a2 := a1 //赋值
    var a3 = make([]int,3,3)
    copy(a3, a1) // copy
    fmt.Println(a1, a2, a3)
    a1[0] = 100
    fmt.Println(a1, a2, a3)
    

    指针

    Go语言中不存在指针操作,只需要记住两个符号:

    1. &:取地址
    2. *:根据地址取值

    make和new的区别

    1. make和new都是用来申请内存的
    2. new很少用,一般用来给基本数据类型申请内存,stringint,返回的是对应类型的指针(*string、*int)。
    3. make是用来给slicemapchan申请内存的,make函数返回的的是对应的这三个类型本身

    map

    map也是引用类型,必须初始化之后才能使用。

    func main() {
    	var m1 map[string]int
    	fmt.Println(m1 == nil)        // 还没有初始化(没有在内存中开辟空间)
    	m1 = make(map[string]int, 10) // 要估算好该map容量,避免在程序运行期间再动态扩容
    	m1["a"] = 18
    	m1["b"] = 35
    
    	fmt.Println(m1)
    	fmt.Println(m1["a"])
    	// 约定成俗用ok接收返回的布尔值
    	fmt.Println(m1["a"]) // 如果不存在这个key拿到对应值类型的零值
    	value, ok := m1["a"]
    	if !ok {
    		fmt.Println("查无此key")
    	} else {
    		fmt.Println(value)
    	}
    
    	// map的遍历
    	for k, v := range m1 {
    		fmt.Println(k, v)
    	}
    	// 只遍历key
    	for k := range m1 {
    		fmt.Println(k)
    	}
    	// 只遍历value
    	for _, v := range m1 {
    		fmt.Println(v)
    	}
    	// 删除
    	delete(m1, "a")
    	fmt.Println(m1)
    	delete(m1, "c") // 删除不存在的key
    }
    

    函数

    // 函数
    
    // 函数存在的意义?
    // 函数是一段代码的封装
    // 把一段逻辑抽象出来封装到一个函数中,给它起个名字,每次用到它的时候直接用函数名调用就可以了
    // 使用函数能够让代码结构更清晰、更简洁。
    
    // 函数的定义
    func sum(x int, y int) (ret int) {
    	return x + y
    }
    
    // 没有返回值
    func f1(x int, y int) {
    	fmt.Println(x + y)
    }
    
    // 没有参数没有返回值
    func f2() {
    	fmt.Println("f2")
    }
    
    // 没有参数但有返回值的
    func f3() int {
    	ret := 3
    	return ret
    }
    
    // 返回值可以命名也可以不命名
    
    // 命名的返回值就相当于在函数中声明一个变量
    func f4(x int, y int) (ret int) {
    	ret = x + y
    	return // 使用命名返回值可以return后省略
    }
    
    // 多个返回值
    func f5() (int, string) {
    	return 1, "沙河"
    }
    
    // 参数的类型简写:
    // 当参数中连续多个参数的类型一致时,我们可以将非最后一个参数的类型省略
    func f6(x, y, z int, m, n string, i, j bool) int {
    	return x + y
    }
    
    // 可变长参数
    // 可变长参数必须放在函数参数的最后
    func f7(x string, y ...int) {
    	fmt.Println(x)
    	fmt.Println(y) // y的类型是切片 []int
    }
    
    // Go语言中函数没有默认参数这个概念
    
    func main() {
    	r := sum(1, 2)
    	fmt.Println(r)
    
    	_, n := f5()
    	fmt.Println(n)
    
    	f7("下雨了")
    	f7("下雨了", 1, 2, 3, 4, 5, 6, 7)
    }
    
  • 相关阅读:
    Java程序员:一整个项目的具体开发流程介绍
    JAVA常用API整理
    Java开发人员必知必会的20种常用类库和API
    SpringBoot_web开发【实验】-员工列表-链接高亮&列表完成
    luogu P1754 球迷购票问题 |动态规划
    luogu P1566 加等式 |背包问题方案数
    luogu P1564 膜拜 |动态规划
    luogu P1509 找啊找啊找GF |背包
    P1474 货币系统 Money Systems |背包方案数
    cloudera安装报错 socket.gaierror: [Errno -2] Name or service not known
  • 原文地址:https://www.cnblogs.com/csp813/p/15223444.html
Copyright © 2020-2023  润新知