zoukankan      html  css  js  c++  java
  • 20200325 switch,数组,切片与map

    昨日回顾

    // 函数
    函数 func 函数名(参数1 类型, 参数2 类型)(返回值类型,返回值){函数体}
    https://saohu156.com
    只有一个返回值
    如果只有return,后面什么都不写,相当于无返回值
    可变长参数, func 函数名(参数1, ...类型)(){函数体}
    匿名函数:没有名字的函数(必须定义在函数内部)  func()(){}
    函数的类型: 函数的参数,返回值都是类型的一部分
    内层函数的返回 main函数中调用 接受需要先定义变量的类型
    闭包: 定义在函数内部,对外部组用于有引用  >> 闭包多了一种给函数传参的方式
    赋返回值,如果有一个或多个,不接受
    
    // if-else
        if 初始值;条件{
    
        }else if 条件{
    
        }else{
    
        }
    
    // for: go中只有for循环
        for 第一部分初始化;第二部分条件;第三部分自增/自减 i+=2/i=i+2{循环体内容}
        break
        continue
    
    

    go进阶

    1. switch

    使用

    多条件判断,用于替换if else

    func main() {
        var a=11
        switch a{
            case 8:
            	fmt.Println("8")
            case 9:
            	fmt.Println("9")
            case 10:
            	fmt.Println("10")
            default:  //上面的条件都不符合的话,执行
            	fmt.Println("我不知道")
        }
    }
    

    多条件

    func main() {
        var a=11
        switch a{
            case 7,8,9:
            	fmt.Println("8")
            case 10,11,12:
            	fmt.Println("9")
            case 13,15:
            	fmt.Println("10")
            default:  //上面的条件都不符合的话,执行
            	fmt.Println("我不知道")
        }
    }
    

    无表达式

    func main() {
        var a=test()	//判断一个函数的执行结果
        switch {	//不加表达式
            case a==8:
            	fmt.Println("8")
            case a==100:
            	fmt.Println("100")
            case a==80:
            	fmt.Println("80")
            case a ==10 || a==11:
            	fmt.Println("这就是or")
            default:  //上面的条件都不符合的话,执行
            	fmt.Println("我不知道")
        }
    }
    

    and与or

    and    &&
    or	   ||
    

    Fallthrough

    无条件执行下一个case中的代码

    func main() {
        var a=test()	//判断一个函数的执行结果
        switch {	//不加表达式
            case a==8:
            	fmt.Println("8")
            	fallthrough   // 无条件执行下一个case中的代码
            case a==100:
            	fmt.Println("100")
            	fallthrough   // 无条件执行下一个case中的代码
    			// break 其他语言的不加break就是fallthrough
            
            default:  //上面的条件都不符合的话,执行
            	fmt.Println("我不知道")
        }
    }
    

    2. 数组array

    数组是同一类元素的集合,类似于python中的列表(列表中可以放任意元素)

    python中为什么能放任意类型的元素
    	python中一切皆对象,对象是一个引用(内存地址)
    
    数组:
    定义了一个长度为3的int类型数组
    每一格的所占内存都是一样大小的,所有类型必须一致(连续存储的同一类元素)
    

    数组的声明

    数组有大小,放的数据类型. 定义阶段长度固定了,以后不能改

    func main(){
        // 定义了一个长度为3的int类型数组
        var a [3]int
        fmt.Println(a)   // 打印 [0 0 0]
        // 定义了一个长度为5的string类型数组
        var a [5]string
        fmt.Println(a)   // 打印 [     ]
    }
    
    
    ------------------------------------------------------------
    
    int 默认值是 0
    string 默认值是 ""
    bool 默认值是false
    数组 默认值 跟他的数据是有关系的,数组存放类型的空值
    

    定义并初始化

    func main(){
        // 三种方式
        var a [3]int = [3]int{1,2,3}
        var a=[3]int{1,2,3}
        a :=[3]int{1,2,3}
        // 使用
        fmt.Println(a[2])
    }
    

    例子

    // 只想把第29个位置设置为1,其他都是0
    func main(){
        var a [30]int=[30]int{28:1,29:9999}
        fmt.Println(a)
    }
    
    
    // 使用...
    func main(){	// 数组在定义阶段就是固定长度的,所以没有可变长
        a := [...]int{28:1,29:9999}  // 这里根据最大长度设置数组 29
        a := [...]int{2,3,4}  // 这个长度为3
        fmt.Println(a)
    }
    
    // 不能超长
    
    

    数组是值类型

    值类型跟引用类型相对应: 当函数传参时,传到函数内部,修改数组,不会影响原来的

    -- go中的函数传参,都是copy传递 --
    	a:=10
    	test(a)  //传入test中的a都是copy传递,不会对原a进行改变
    	
    引用类型: 传递过去的就是引用地址
    值类型: 传递的是copy的值
    
    
    -- python中可变类型与不可变类型 --
    一切皆对象,都是引用
        python强行将数字字符串元组做成不可变数据类型,当做函数传参时,在函数中修改.
        	- 不可变数据类型,不会修改原来的
        	- 其他的,在函数中修改,都会影响原来的
    
    python是值传递还是引用传递
    	统一使用的都是引用传递
    

    go语言中保留了指针,可以传递地址.

    func main(){
        var a=[3]int{2,4,6}
        fmt.Println(a)   // [2 4 6]
        test(a)
        fmt.Println(a)  // [2 4 6]
    }
    
    
    func test(a [3]int){
        x[0] = 999
        fmt.Println(a)  // [999 4 6]
    }
    

    数组长度len()

    len
    

    循环数组使用range 迭代数组

    // 第一种: 普通循环
    func main(){
        var a=[3]int{2,4,6}
        for i:=0;i<len(a);i++{
            fmt.Println(a[i])
        }
    }
    
    // 第二种:使用range   :range不是一个内置函数,他是一个关键字
    i := range a   i是索引,一个值来接受,就是索引
    i,v := range a   i是索引,两个值来接受,索引与值
    _,v := range a    使用_来不接受索引,只接受值
    
    // 索引
    var a =[3]int{2,3,4}
    for i := range a{
        fmt.Println(i)
    }
    
    // 索引与值
    var a =[3]int{2,3,4}
    for i,v := range a{
        fmt.Println(i)
        fmt.Println(v)
    }
    
    // 值
    var a =[3]int{2,3,4}
    for _,v := range a{
        fmt.Println(v)
    }
    

    多维数组

    数组套数组

    定义并初始化

    var a [3][3]int = [3][3]int{1,2,3}{2,3,4}{5,6,7}
    

    使用

    var a[3][3]int
    a[0][1]=999
    fmt.Println(a)
    // [ [0 999 0] [0 0 0] [0 0 0]]
    
    
    // 三维数组
    var a [3][3][3]int
    fmt.Println(a)
    

    数组的大小是类型的一部分

    var a[3]int
    var a[4]int
    // 只要数组不一样,他们的类型就不一致
    

    3. 切片 slice

    由于go中的数组类型,其长度是固定的,无法改变。在很多场景下我们需要动态改变数组的长度,因而go中内置了slice类型,称其为数组的一种抽象(可看作是动态数组)。slice与数组很相似,只是长度可变,可追加元素
    

    切片是由数组建立的一种方便灵活功能强大的包装

    切片本身不拥有任何数据,只是对现有数据的引用

    1. 切片的初始化

    切片初始化的三种方式

    • 通过make函数
    • 通过字面量方式
    • 对源数组或源切片使用identifier[start:end] 语法生成切片
    package main
    import (
    	"fmt"
    )
     
    func main() {
        
    	//make切片
    	var s0 []int = make([]int,3,5)  //切片类型、切片长度、切片容量
    	fmt.Println(len(s0),cap(s0),s0)
        //--> 3 5 [0 0 0]	
     
        
        
    	//字面量切片
    	var s1 []int = []int{1,2,3}     //切片的元素
    	fmt.Println(len(s1),cap(s1),s1)
        //--> 3 3 [1 2 3]
     
        
        
        
    	//从数组切片,这里先定义一个数组a
    	var a [10]int
    	s2 := a[:3]                     //从数组a的第0个到第3个元素生成切片
    	fmt.Println(len(s2),cap(s2),s2)
        //--> 3 10 [0 0 0]
     
    	//从s2切片
    	s4 := s2[:2]
    	fmt.Println(len(s4),cap(s4),s4)
        //-->2 10 [0 0]
    }
    
    
    func main(){
        // 1.创建一个切片
        	// 先创建一个数组
            var a [10]int=[10]int{1,2,3,4,5,6,7,8,9,10}
        // 创建切片(基于上面数组的切出来)
        var b = a[:]    //从0切到最后
        var b = a[5:]    // 从第5切到最后
        var b = a[5:9]  //前闭后开,从第5个到第9个
    }
    

    通过make函数

    切片类型:

    中括号有东西就是数组,没有东西就是数组
    var b[]int = a[5:9]
    

    2.切片的修改

    切片的修改会影响原来的数据,数组的修改也会影响切片

    var a [10]int=[10]int{1,2,3,4,5,6,7,8,9,10}
    var b[]int = a[5:9]
    b[0] = 999  // 切片影响数组
    a[6] = 888  // 数组影响切片
    
    fmt.Println(b)   // [999 7 8 9 ]  
    fmt.Println(b)   // [1 2 3 ... 999 7 ...]
    

    3. 切片的长度和容量

    切片的长度就是它所包含的元素个数。

    切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数

    切片 s 的长度和容量可通过表达式 len(s)cap(s) 来获取。

    长度 len()

    var a [10]int=[10]int{1,2,3,4,5,6,7,8,9,10}
    var b[]int = a[5:9]
    len(b)  // 4
    

    容量 cap()

    总共能放多少值(追加元素)

    cap(b)  // 6
    
        s := []int{1,2,3,4,5}
        fmt.Println(s,len(s),cap(s))    // [1 2 3 4 5] 5 5
        s = s[2:3]
        fmt.Println(s,len(s),cap(s))    // [3] 1 3
        //此时的s就是 [3]  以此为基础访问0:3  打印出 [3 4 5]
        s = s[0:3]
        fmt.Println(s,len(s),cap(s))    // [3 4 5] 3 3
    
    	//var a [10]int=[10]int{1,2,3,4,5,6,7,8,9,10}
    	////var b[]int =a[5:9]
    	////var b[]int =a[0:3]
    	//var b[]int =a[2:3]
    	//fmt.Println(len(b))
    	//fmt.Println(cap(b))
    
    

    4. 使用make创建一个切片

    切片的空值:

    nil类型(引用类型的控制都是nil)

    var a []int
    fmt.Println(a)
    if a==nil{
        fmt.Println("a是nil")
    }
    // a[0]=100   直接报错,不可更改
    

    make

    make是内置函数

    • 第一个参数写类型
    • 第二个参数是切片的长度
    • 第三个参数是切片的容量
    var a []int=make([]int,3,4) 
    fmt.Println(a)  // [0 0 0]
    a[0] = 999
    fmt.Println(a)  // [999 0 0]
    // 中括号只能取长度
    a[2] = 888
    
    
    // 容量如果不传,和长度一样
    var a []int=make([]int,3) 
    

    5. 追加切片元素

    基于make

    var a []int=make([]int,3,4) 
    // 在最后追加一个元素 999
    a = append(a,999)
    fmt.Println(a)	// [0 0 0 999]
    fmt.Println(len(a))	// 4
    fmt.Println(cap(a))	// 4
    
    //再追加一个
    a = append(a,888)
    // 不会报错,追加的时候,一旦超出容量,会重新创建一个数组,让切片指向新的数组,新数组大小是原来的切片容量的两倍
    fmt.Println(a)	// [0 0 0 999 888]
    fmt.Println(len(a))	// 5
    fmt.Println(cap(a))	// 8
    

    切片如果基于数组切出来

    var a [10]int=[10]int{1,2,3,4,5,6,7,8,9,10}
    var b[]int = a[5:9]
    b =append(b,777)
    
    fmt.Println(b)	// [6 7 8 9 777]
    fmt.Println(len(b))	// 5
    fmt.Println(cap(b))	// 5
    fmt.Println(a)	// [1 ... 6 7 8 9 777]
    
    
    // 再添加一个,容量超长,不会影响原来的数组了
    b =append(b,777)
    
    fmt.Println(b)	// [6 7 8 9 777 666]
    fmt.Println(len(b))	// 6
    fmt.Println(cap(b))	// 10
    fmt.Println(a)	// [1 ... 6 7 8 9 777]
    

    重要概念,容量超长,新建一个切片,容量翻倍,此后对切片数组的操作,不会互相影响

    6. 切片的函数传递

    引用类型,传递,修改

    func main(){
        var a []int=make([]int,4,5)
        fmt.Println(a)	//[0 0 0 0 ]
        test(a)
        fmt.Println(a)	// [999 0 0 0]
    }
    
    func test(a []int){
        a[0] = 999
        fmt.Println(a)  //  [999 0 0 0]
    }
    

    7.多维切片

    var a [][]int = make([][]int,3,4)
    fmt.Println(a[0])	// []
    
    
    // 类似数组初始化的 切片初始化
    var b []int = []int{1,2,3,4,5}
    fmt.Println(b)	// [1,2,3,4,5]
    fmt.Println(len(b))	// 5
    fmt.Println(cap(b))	//  5
    
    
    // 多维数组的初始化
    var a [][]int = []int{{1,2,3,4,5},{2,3},{1,3,4,68,5}}
    
    

    8. 切片的copy

    var a []int=make([]int,4,5)
    var b []int = []int{1,2,3,4,5}
    fmt.Println(a)	// [0 0 0 0]
    fmt.Println(b)	// [1 2 3 4 5]
    
    // 把b数据copy到a上
    copy(a,b)
    
    fmt.Println(a)	// [1 2 3 4]
    fmt.Println(b)	// [1 2 3 4 5]
    

    9. 循环切片

    var b []int = []int{1,2,3,4,5}
    for _,v:=range b{
        fmt.Println(v)
    }
    /*
    1
    2
    3
    4
    5
    */
    

    4. map

    哈希,键值对

    map在定义时,key(数字和字符串)与values的类型固定了

    1. 创建map

    map的类型

    map[key的类型]valuse的类型
    
    var a map[int]string
    fmt.Println(a)
    // 空值就是nil  引用类型的空值都是nil
    

    定义并初始化(make完成)

    var a map[int]string=make(map[int]string)
    fmt.Println(a)
    

    定义并初始化,直接赋值

    var a map[int]string = map[int]string{1:"v1",2:"v2",3:"v3"}
    fmt.Println(a)  //    map[1:v1 2:v2 3:v3]
    

    2. 添加元素

    有就是更新,没有就是添加

    //var a map[int]string  // 不能往里添加元素
    
    a :=make(map[int]string )
    a[1] = "jack"   // 添加元素
    a[1] = "cheng"  // 更新了1
    fmt.Println(a)
    

    3.获取元素

        //b:= a[9]
        b,ok := a[9]
        //b,ok := a[1]  // 里面有的就是true
        println(b)   //
        println(ok)   // false
    

    4.删除元素

        //删除元素
        var a map[int]string = map[int]string{1:"lqz",2:"egon",3:"Jason"}
        fmt.Println(a)
        //根据key删除值
        delete(a,1)
        fmt.Println(a)
    

    5.长度

        var a map[int]string = map[int]string{1:"lqz",2:"egon",3:"Jason"}
        a[9] = "999"
        fmt.Println(len(a))
    

    6. 引用类型

    func main(){
        var a map[int]string = map[int]string{1:"lqz",2:"egon",3:"Jason"}
        fmt.Println(a)
        test(a)
        fmt.Println(a)
    }
    
    
    func test (map[int]string){
        a[1]  "9999"
    }
    

    7. map的相等性

        var a map[int]string = map[int]string{1:"lqz",2:"egon",3:"Jason"}
        var b map[int]string = map[int]string{1:"lqz",2:"egon",3:"Jason"}
        if a==b{  //map不能通过等号来判断,自己写循环,一个个取判断
            
        }
    

    8. map的value值可以是任意类型

        var a map[int]map[string]string = make(map[int]map[string]string)
        fmt.Println(a)  //a不是nil 是空
        fmt.Println(a[1])  // nil  也是空
    
        a[1] = make(map[string]string)
        a[1]["1"] = "可以赋值"
        //a[1] = map[string]string{"1":"可以赋值"}
        fmt.Println(a)  //map[1:map[1:可以赋值]]
    

    9. 循环map

        var a = make(map[int]string)
        a[1]="xxx"
        a[2]="x12"
        a[3]="x234"
        a[4]="xx34"
        a[5]="x456"
        a[6]="x78"
    
        //map是无序的,python3.6以后就是有序的
        for k,v :=range a{
            fmt.Println(k)
            fmt.Println(v)
        }
    

    作业

    go中map做成有序
    熟悉go语言: 闭包,函数,可变长,切片底层原理,map
    
  • 相关阅读:
    Flink CEP实例及基础应用
    seata 分布式事务
    skywalking 分布式链路追踪
    datax 离线数据同步工具
    rocketmq 消息队列
    Nacos 服务注册
    跨站(cross-site)、跨域(cross-origin)、SameSite与XMLHttpRequest.withCredentials
    读写二进制文件与文本文件
    WPF中通过双击编辑DataGrid中Cell(附源码)
    记一次XML文件读取优化
  • 原文地址:https://www.cnblogs.com/fwzzz/p/12734534.html
Copyright © 2011-2022 走看看