Go语言基础学习 (二) -Go语言中的类型转与Go语言中的数组切片

199 阅读4分钟

前言

在极客上看了蔡超老师的Go语言课程 随手记下来的一些随笔,Go的基础应用及实例, 系列内容比较偏基础,推荐给想要入门Go语言开发者们阅读。

目录如下

Go语言基础学习 (一) - 变量 常量已经与其他语言的差异
Go语言基础学习 (二) -Go语言中的类型转与Go语言中的数组切片
Go语言基础学习 (三) - Go语言内的 Map声明使用与工厂模式
Go语言基础学习 (四) - Go语言函数简单介绍
Go语言基础学习 (五) - 面向对象编程
Go语言基础学习 (六) - 编写一个好的错误处理
Go语言基础学习 (七) - 包(package)
Go语言基础学习 (八) - 并发编程

1. Go语言中的类型转换

  • 与其他语言的差异

    1. Go语言不允许隐式类型转换

    2. 别名和原有类型也不能进行隐式类型转换

  • Go 语言内数据类型是不支持强行转换
    package type_test
    
    import (
       "fmt"
       "testing"
    )
    
    func TestImplicit(t *testing.T)  {
    
       var a int32   =  1
       var b int64
       b = a
    
       fmt.Println(a,b)
    }
    

    开始编译执行时就会报错

      # go_test/src/v3/type_test_test [go_test/src/v3/type_test.test]
      ./type_test.go:12:4: cannot use a (type int32) as type int64 in assignment
    

    原因为两个变量类型不同,不可进行转换

    解决方案: 使用相同数据类型来进行转换

     package type_test
    
    import (
            "fmt"
            "testing"
    )
    
    func TestImplicit(t *testing.T)  {
    
            var a int32   =  1
            var b int64
            b = int64(a)
    
            fmt.Println(a,b)
    }
    
    1,1
    

2. 数组声明及切片

  • 数组声明

    image-20220210164111244.png

  • 数组截取

    image-20220210165258648.png

  • Slice切片(存储结构)

    image-20220210165536707.png

    1. 指针 ptr 指向一连串的存储空间
    2. len 元素个数 (初始化或者设置的值
    3. cap 空间长度
  • 数组常用到的函数

    len 获取长度 cap 获取空间长度 内建函数 make用来为 slicemapchannel类型分配内存和初始化一个对象(注意:只能用在这三种类型上)

    看一下代码实例

    
    package slice_test
    
    import "testing"
    
    func TestSliceTest( t *testing.T)  {
    
           var a0 []int
           t.Log(len(a0),cap(a0))  // 结果为 0 0    初始化默认值
           a0 = append(a0,1)    // 使用append  新增元素
           t.Log(len(a0),cap(a0))  //  结果就为 1 1   
           a2 := []int{1,2,3,4}
           t.Log(len(a2),cap(a2))     // 结果为 4 4 
    
           a3 := make([]int,3,5)      // 使用make声明一个slice, 第一个参数为初始化的值,第二个为长度 len , 第三个为cap 空间
           t.Log(len(a3),cap(a3))	    //结果为 3 5 
           a3  = append(a3,2)          // 新插入一个元素  
           t.Log(a3[0],a3[1],a3[2],a3[3]) // 结果就会为 0 0 0 2   
           t.Log(len(a3),cap(a3))  // 结果为  4 5.    // 长度从 3 变成了  是因为新插入一个元素
    
    }
    
  • Cap空间自增
    func TestSliceFor(t *testing.T)  {
    a1:=[]int{}
    for i :=0;i<17 ;i++  {
       a1 = append(a1,i)
       t.Log(len(a1),cap(a1))
    }
    
       }
    
       // 结果
       --- PASS: TestSliceFor (0.00s)
        slice_test.go:26: 1 1
        slice_test.go:26: 2 2
        slice_test.go:26: 3 4
        slice_test.go:26: 4 4
        slice_test.go:26: 5 8  
        slice_test.go:26: 6 8
        slice_test.go:26: 7 8
        slice_test.go:26: 8 8
        slice_test.go:26: 9 16
        slice_test.go:26: 10 16
        slice_test.go:26: 11 16
        slice_test.go:26: 12 16
        slice_test.go:26: 13 16
        slice_test.go:26: 14 16
        slice_test.go:26: 15 16
        slice_test.go:26: 16 16
        slice_test.go:26: 17 32
    

    通过代码打印结果可以看出,创建一个新的数组切片,往里面插入数据,插入第一个数据的时候,cap(空间)是1,插入第二个的时候cap明显空间不够插入第二个数据,它就会递增来增加空间,第三个空间也不够,cap在进行倍增,所以它会以倍增的方式来增加cap的存储空间。

  • 切片共享存储

    image-20220211143333873.png months 切片中,截取两个切片 Q2summer ,在进行单独修改Q2 中的元素时,summer中所对应的下标元素则也会改变

    func TestSliceShareMemory(t *testing.T){
    year :=[]string{"Jan","Feb","mar","Apr","May","Jun","Jul","Aug","Sep","Sep2","Sep3","Sep5"}
    a := year[3:6]
    t.Log(year) // [Jan Feb mar Apr May Jun Jul Aug Sep Sep2 Sep3 Sep5] 
    t.Log(a,len( a),cap(a)) // [Apr May Jun] 3 9    
    
    b := year[5:8]
    t.Log(b,len(b),cap(b)) // [Jun Jul Aug] 3 7
    
    b[0] = "Unknow"
    
    c := year[:6]   
    c[0] = "aaa"
    
    t.Log(a)   // [Apr May Unknow]   并未改变a的元素,但是因为改变了b的元素,其中b改变的元素中也存在有a的元素, 因为共享储存的原因 所以会直接一起改变   
    t.Log(c)   // [aaa Feb mar Apr May Unknow]
    t.Log(year) // [aaa Feb mar Apr May Unknow Jul Aug Sep Sep2 Sep3 Sep5]
    }