美文网首页
5.Go语言数组和切片(二)

5.Go语言数组和切片(二)

作者: 一枼落知天下 | 来源:发表于2019-05-29 17:41 被阅读0次

    main.go

    // Go语言数组和切片
    package main
    
    //  包的本质是创建不同的文件夹
    //  go的每一个文件都是属于一个包的
    //  go以包的形式管理项目和文件目录。
    //  import "包的路径"
    import (
         "day7/model/utils" 
        _"fmt"
    )
    
    
    var content string = `
    ————————————————Go语言数组和切片————————————————————
    一、数组
    二、切片
    
    `
    
    
    /**
     * [init init函数初始化工作。main函数之前执行]
     * @author Jhou Shuai
     * @datetime 2019-05-20T22:49:36+0800
     */
    // func init() {
    //  fmt.Println(content)
    // }
    
    
    func main() {
        utils.Entry()
    }
    
    

    utils.go

    // Go语言数组和切片
    package utils
    
    import (
        "fmt"
        "strings"
    )
    
    var layout string = "2006-01-02"
    
    // 全局变量
    var Author string = "Jhou Shuai"
    
    // 全局变量
    var Description string = "Go语言数组和切片"
    
    //全局变量:使用反引号来定义多行字符串
    var Content string = `
    ————————————————Go语言数组和切片————————————————————
    一、数组
        1)数组是值类型:
        2)数组可以存放多个同一类型的数据
        3)增加程序可维护性
        4)代码更加清晰,易扩展
    二、切片
        1.切片的长度是可以变化的,是一个动态变化数组
        切片的容量是可以动态变化的
        var 切片名 []类型
        var intSlice []int 
        第一种: mySlice := intArr[1:3]
        2.切片在内存中的表现形式
        3.切片引用类型:在传递时候,遵守引用传递机制
        4.数据结构:struct结构体
            type slicestuct{
                ptr *[2]int
                len int
                cap int
            }
        5.第二种:make 创建切片
            类型,长度,容量
            cap>=len
            var 切片名 []type = make([]type,len,[cap])
            var slice []float64 = make([]float64, 5,10)
    
        6.第三种:定义一个切片,直接就指定具体的数组
        var strSlice []string = []string{"Faker","Uzi","Mata"}
    `
    
    /**
     * [Init 入口]
     * @author Jhou Shuai
     * @datetime 2019-05-18T11:58:33+0800
     */
    func Entry() {
        [1 1 2 3 5 8 13 21 34 55]
        fmt.Println(fbn(10))
    }
    
    
    func sliceInit() {
        // 第一种方式:
        // var intArr [5]int = [...]int{1,22,33,44,55}
        // // 切片操作:
        // // 1.
        // // 引用intArr数组的起始下标为1,最后的下标为3(不包含3)
        // mySlice := intArr[1:3]
        // fmt.Println("intArr= ",intArr)
        // fmt.Println("mySlice中的元素:",mySlice)
        // fmt.Println("mySlice中的长度:",len(mySlice))
        // // 切片的容量是可以动态变化的
        // fmt.Println("mySlice中的容量:",cap(mySlice))
    
        // fmt.Println()
        // // 数组的各个元素的地址间隔是依据数组的类型决定的,
        // //      比如:int64->8个字节、int32->4个字节 int16 ->2个字节 、int->8个字节
        // fmt.Printf("intArr地址%p \n",&intArr)
        // for i := 0; i <len(intArr); i++ {
        //     fmt.Printf("intArr[%v]的地址%p \n",i,&intArr[i])
        // }
    
        // fmt.Println()
        // fmt.Printf("mySlice地址%p \n",&mySlice)
        // for i := 0; i <len(mySlice); i++ {
        //     fmt.Printf("mySlice[%v]的地址%p \n",i,&mySlice[i])
        // }
    
        // mySlice[1] = 66
        // fmt.Println("intArr= ",intArr)
        // fmt.Println("mySlice中的元素:",mySlice)
    
        // 第二种方式:
        fmt.Println()
        var slice []float64 = make([]float64, 5,10)
        // 对于切片必须,make才能使用 
        // [0 0 0 0 0] 默认全部为零
        slice[1] = 64
        slice[3] = 100
        fmt.Printf("元素:%v,长度:%v,容量:%v \n",slice,len(slice),cap(slice))
        for i := 0; i <len(slice); i++ {
            fmt.Printf("slice[%v]的地址%p \n",i,&slice[i])
        }
        // 元素:[0 64 0 100 0],长度:5,容量:10
        // slice[0]的地址0xc0000700f0
        // slice[1]的地址0xc0000700f8    0xc0000700f8  = 0xc0000700f0 + 8
        // slice[2]的地址0xc000070100    0xc000070100  = 0xc0000700f8 + 8
        // slice[3]的地址0xc000070108    0xc000070108  = 0xc000070100 + 8
        // slice[4]的地址0xc000070110    0xc000070110  = 0xc000070108 + 8
    
        // 通过make方式创建切片可以指定切片的大小和容量
        // 如果没有给切片的各个元素赋值,那么就会使用默认值
        //      int float => 0
        //      string => ""
        //      bool => false
        //  通过make方式创建的切片对应的数组是由make底层维护,对外
        //  不可见,即只能通过slice去访问各个元素。
        //  
        // 第三种方式:
        fmt.Println()
        var strSlice []string = []string{"Faker","Uzi","Mata"}
        fmt.Printf("元素:%v,长度:%v,容量:%v \n",strSlice,len(strSlice),cap(strSlice))
        for i := 0; i <len(strSlice); i++ {
            fmt.Printf("strSlice[%v]的地址%p \n",i,&strSlice[i])
        }
        // 元素:[Faker Uzi Mata],长度:3,容量:3
        // strSlice[0]的地址0xc000080300
        // strSlice[1]的地址0xc000080310   0xc000080310 = 0xc000080300 + 16
        // strSlice[2]的地址0xc000080320   0xc000080320 = 0xc000080310 + 16
        // 
        // 
        //  第一种方式和第二种方式的区别:
        //  第一种方式:
        //      直接引用数组,这个数组是事先存在的,是可见的
        //  第二种方式:
        //      通过make来创建切片,make也会创建一个数组,是由切片在
        //   底层维护,是不可见的
    }
    
    
    func sliceForRange() {
        var intArr [5]int = [...]int{10,20,30,40,50}
    
        intSlice := intArr[0:]
    
        for i := 0; i <len(intSlice); i++ {
            fmt.Printf("intSlice[%v] = %v \n",i,intSlice[i])
        }
    
        fmt.Println()
        for key,value := range intSlice {
             fmt.Printf("intSlice[%v] = %v \n",key,value)
        }
    
        fmt.Println()
        for _,value := range intSlice {
             fmt.Printf( "%v \t",value)
        }
    }
    
    /**
     * [sliceUseDetail 切片注意事项和细节说明]
     * @author Jhou Shuai
     * @datetime 2019-05-29T20:41:33+0800
     */
    func sliceUseDetail() {
        // 不要越界
        // var slice = arr[startIndex,endIndex]
        // 从arr数组下标startIndex,取到下标为endIndex的元素(不含arr[endIndex])
        // var slice = arr[:len(arr)]
        // var slice = arr[start:]
        // var slice = arr[:end]
        // var slice = arr[:]
        // 
        // cap 容量
        // 可以多次切片,切了在切,
        // 
        // append 内置函数 
        // 可以对切片进行动态追加
        var intSlice []int = []int{100,200,300}
        fmt.Println(intSlice)
        for i := 0; i <len(intSlice); i++ {
            fmt.Printf("intSlice[%v]的地址%p \n",i,&intSlice[i])
        }
        // 通过append直接给intSlice追加元素
        intSlice0 := append(intSlice,400,500)
    
    
        fmt.Println(intSlice0)
        for i := 0; i <len(intSlice0); i++ {
            fmt.Printf("intSlice0[%v]的地址%p \n",i,&intSlice0[i])
        }
        // 通过append将切片intSlice追加给intSlice
        intSlice = append(intSlice,intSlice...)
        fmt.Println(intSlice)
        // 切片append操作的本质是对数组扩容
        // 不是针对原来的数组,而是
        // go底层会创建一个新的数组newArr(按照扩容后大小)
        // 刚创建所有默认值为零;然后
        // 将intSlice原来包含的元素拷贝到新的数组newArr
        // 切片intSlice重新应用新数组newArr
        // 新的数组newArr是在底层维护,不可见的
        // 原来的数组就会被回收。
        
        // 切片的拷贝 copy 两个参数的数据类型:切片
        // 两个切片的数据空间是独立。相互不影响
        // 切片类型才可以执行copy
        fmt.Println()
        var slice4 []int = []int{1,2,3,4,5};
        var slice5 = make([]int, 10)
        copy(slice5,slice4)
        fmt.Println(slice4)
        for i := 0; i <len(slice4); i++ {
            fmt.Printf("slice4[%v]的地址%p \n",i,&slice4[i])
        }
        //     [1 2 3 4 5]
        // slice4[0]的地址0xc000094090
        // slice4[1]的地址0xc000094098
        // slice4[2]的地址0xc0000940a0
        // slice4[3]的地址0xc0000940a8
        // slice4[4]的地址0xc0000940b0
    
        fmt.Println(slice5)
        for i := 0; i <len(slice5); i++ {
            fmt.Printf("slice5[%v]的地址%p \n",i,&slice5[i])
        }
        //      [1 2 3 4 5 0 0 0 0 0]
        // slice5[0]的地址0xc0000700f0
        // slice5[1]的地址0xc0000700f8
        // slice5[2]的地址0xc000070100
        // slice5[3]的地址0xc000070108
        // slice5[4]的地址0xc000070110
        // slice5[5]的地址0xc000070118
        // slice5[6]的地址0xc000070120
        // slice5[7]的地址0xc000070128
        // slice5[8]的地址0xc000070130
        // slice5[9]的地址0xc000070138
    
        // slice5,slice4是两个相互独立的空间
        // 
        
        // 不会报错,只会拷贝一个
        var slice6 = make([]int, 1)
        copy(slice6,slice4)
        // [1]
        fmt.Println(slice6)
    }
    
    
    /**
     * [stringSlice 字符串、切片]
     * @author Jhou Shuai
     * @datetime 2019-05-29T22:15:32+0800
     */
    func stringSlice() {
        // string底层是一个byte数组,因此也可以进行切片处理
        // string和切片在内存的形式:
        var name string = "ZhouShuai@163.com"
    
        var strSlice =name[strings.Index(name,"@"):]
    
        fmt.Println(strSlice)
    
        // string是不可变的,也就是不能通过str[0]='z'方式来修改字符串
        // 
        // 
        // 如果需要修改字符串,可以将string-》[]byte 或[]rune->修改-》重写转成string
        arrSlice := []byte(name)
        arrSlice[0]='J'
        var arrStr = string(arrSlice)
        // JhouShuai@163.com
        fmt.Println(arrStr)
        // []byte
        // 转成[]byte后,可以处理英文和数字,不能处理中文
        // 原因是[]byte字节来处理,而一个汉字,是三个字节,因此会出现乱码
        // 
        // []rune
        // 解决方法是:将string 转成[]rune 即可,因为[]rune是按字符处理的
        // 可以兼容汉字
    
        arrSlice1 := []rune(name)
        arrSlice1[0]='周'
        var arrStr1 = string(arrSlice1)
        // 周houShuai@163.com
        fmt.Println(arrStr1)
    }
    
    /**
     * [fbn 斐波拉契数列]
     * @author Jhou Shuai
     * @datetime 2019-05-29T22:59:40+0800
     * [1 1 2 3 5 8 13 21 34 55]
     * fmt.Println(fbn(10))
     */
    func fbn(n int) ([]uint64) {
        /**
         * 思路:
         * 1.声明一个函数,fbn(n int) ([]uint64){}
         */
         var fbnSlice = make([]uint64, n)
         fbnSlice[0] = 1
         fbnSlice[1] = 1
         for i := 2; i <n; i++ {
            fbnSlice[i] = fbnSlice[i-1] + fbnSlice[i-2]
         }
         return fbnSlice
    }
    

    相关文章

      网友评论

          本文标题:5.Go语言数组和切片(二)

          本文链接:https://www.haomeiwen.com/subject/defutctx.html