zoukankan      html  css  js  c++  java
  • golang之类型零值初始化及比较

    1. 综述

    变量声明时未赋初值,则变量被自动赋值为该类型的零值(固定值)

    func new(Type) *Type

    new()返回一个指针,指向新分配的该类型的零值,不是空指针(nil)。the value returned is a pointer to a newly allocated zero value of that type.

    func make(t Type, size ...IntegerType) Type

    make()只适用于slicemapchan,此三种类型创建时推荐使用make()而不是new()The make built-in function allocates and initializes an object of type slice, map, or chan (only). Unlike new, make's return type is the same as the type of its argument, not a pointer to it. The specification of the result depends on the type:

    Slice: The size specifies the length. The capacity of the slice is equal to its length. A second integer argument may be provided to specify a different capacity; it must be no smaller than the length. For example, make([]int, 0, 10) allocates an underlying array of size 10 and returns a slice of length 0 and capacity 10 that is backed by this underlying array.
    Map: An empty map is allocated with enough space to hold the specified number of elements. The size may be omitted, in which case a small starting size is allocated.
    Channel: The channel's buffer is initialized with the specified buffer capacity. If zero, or the size is omitted, the channel is unbuffered.

    如下将按照类型实体、指针、new/make、类型比较等详述各种数据类型。

    2. 数组

    数组是值类型而不是引用类型。当数组赋值给一个变量时,该变量会得到一个原始数组的副本。对新变量的更改,不会影响原始数组。

    数组实体被初始化数组值类型的零值,如int零值为0string零值为""

    数组指针初始化为nil

    new()返回指向类型零值的指针。 

    数组是值类型,可以直接比较。

    package main
    
    import (
        "fmt"
        "strconv"
    )
    
    func main(){
        var ai [10]int
        var as [10]string
        fmt.Printf("int array [%p] init value: %v
    ", &ai, ai)
        fmt.Printf("string array [%p] init value: %v
    ", &as, as)
        fmt.Println("---------------------------")
    
        var i int
        for i = 0; i < len(ai); i++ {
            ai[i] = 100 + i
        }
    
        for i, _ := range as {
            as[i] = strconv.Itoa(100 + i)
        }
        fmt.Printf("int array [%p] init value: %v
    ", &ai, ai)
        fmt.Printf("string array [%p] init value: %v
    ", &as, as)
        fmt.Println("---------------------------")
    
        var pai *[10]int
        var pas *[10]string
        fmt.Printf("int point array [%p] init value: %v
    ", &pai, pai)
        fmt.Printf("string point array [%p] init value: %v
    ", &pas, pas)
        fmt.Println("---------------------------")
    
        pai = &ai
        pas = &as
        pai[0] = 1
        pas[0] = "1"
        fmt.Printf("int point array [%p] init value: %v
    ", &pai, *pai)
        fmt.Printf("string point array [%p] init value: %v
    ", &pas, *pas)
        fmt.Println("---------------------------")
    
        paii := new([10]int)
        pass := new([10]string)
        fmt.Printf("int point array [%p] init value: %v
    ", &paii, *paii)
        fmt.Printf("string point array [%p] init value: %v
    ", &pass, *pass)
        fmt.Println("---------------------------")
    
        for i = 0; i < len(*paii); i++ {
            paii[i] = 100 + i
        }
        for i, _ := range *pass {
            pass[i] = strconv.Itoa(100 + i)
        }
        fmt.Printf("int point array [%p] init value: %v
    ", &paii, *paii)
        fmt.Printf("string point array [%p] init value: %v
    ", &pass, *pass)
        fmt.Println("---------------------------")
    
        paii[0] = 1
        pass[0] = "1"
        fmt.Printf("%v
    ==
    %v 
    ???
    %t
    ", ai, *paii, (ai==*paii))
        fmt.Println("---------------------------")
        fmt.Printf("%v
    ==
    %v 
    ???
    %t
    ", as, *pass, (as==*pass))
    }

    运行结果:

    int array [0xc000072000] init value: [0 0 0 0 0 0 0 0 0 0]
    string array [0xc000074000] init value: [         ]
    ---------------------------
    int array [0xc000072000] init value: [100 101 102 103 104 105 106 107 108 109]
    string array [0xc000074000] init value: [100 101 102 103 104 105 106 107 108 109]
    ---------------------------
    int point array [0xc00000e030] init value: <nil>
    string point array [0xc00000e038] init value: <nil>
    ---------------------------
    int point array [0xc00000e030] init value: [1 101 102 103 104 105 106 107 108 109]
    string point array [0xc00000e038] init value: [1 101 102 103 104 105 106 107 108 109]
    ---------------------------
    int point array [0xc00000e040] init value: [0 0 0 0 0 0 0 0 0 0]
    string point array [0xc00000e048] init value: [         ]
    ---------------------------
    int point array [0xc00000e040] init value: [100 101 102 103 104 105 106 107 108 109]
    string point array [0xc00000e048] init value: [100 101 102 103 104 105 106 107 108 109]
    ---------------------------
    [1 101 102 103 104 105 106 107 108 109]
    ==
    [1 101 102 103 104 105 106 107 108 109]
    ???
    true
    ---------------------------
    [1 101 102 103 104 105 106 107 108 109]
    ==
    [1 101 102 103 104 105 106 107 108 109]
    ???
    true

      

    3. 切片

    切片是值类型而不是引用类型。切片本身不拥有任何数据,只是对现有数组的引用。对切片的所有修改都会反映到底层数组上。

    切片实体初始化为切片类型的零值 nil。一个 nil 切片的长度和容量为 0

    切片指针初始化为nil

    make返回类型零值的切片,非nil

    切片只能和nil作比较,要比较切片需比较切片的每个元素值。

    package main
    
    import (
        "fmt"
        "strconv"
    )
    
    func main(){
        var si []int
        var ss []string
        fmt.Printf("int slice [%p] init value: %v, len:%d, cap:%d
    ", &si, si, len(si), cap(si))
        fmt.Printf("string slice [%p] init value: %v, len:%d, cap:%d
    ", &ss, ss, len(ss), cap(ss))
    //    fmt.Printf("int slice [%p] init value: %v
    ", &si, si[0])
    //    fmt.Printf("string slice [%p] init value: %v
    ", &ss, ss[0])
        fmt.Println("---------------------------------------")
    
        var i int
        if si == nil {
            for i = 0; i < 10; i++ {
                si = append(si, 100+i)
                fmt.Printf("int slice [%p] append %d element: %v, len:%d, cap:%d
    ", &si, i, si, len(si), cap(si))
            }
        }
        fmt.Println("---------------------------------------")
        if ss == nil {
            for i = 0; i < 10; i++ {
                ss = append(ss, strconv.Itoa(100+i))
                fmt.Printf("string slice [%p] append %d element: %v, len:%d, cap:%d
    ", &ss, i, ss, len(ss), cap(ss))
            }
        }
        fmt.Println("---------------------------------------")
        
        var psi *[]int
        var pss *[]string
    //    fmt.Printf("int slice pointer [%p] init value: %v, len:%d, cap:%d
    ", &psi, psi, len(*psi), cap(*psi))
    //    fmt.Printf("string slice pointer [%p] init value: %v, len:%d, cap:%d
    ", &pss, pss, len(*pss), cap(*pss))
        fmt.Printf("int slice pointer [%p] init value: %v
    ", &psi, psi)
        fmt.Printf("string slice pointer [%p] init value: %v
    ", &pss, pss)
        fmt.Println("---------------------------------------")
        psi = &si
        pss = &ss
        fmt.Printf("int slice pointer [%p] init value: %v, len:%d, cap:%d
    ", &psi, *psi, len(*psi), cap(*psi))
        fmt.Printf("string slice pointer [%p] init value: %v, len:%d, cap:%d
    ", &pss, *pss, len(*pss), cap(*pss))
        fmt.Println("---------------------------------------")
    
        sim := make([]int, 10, 10)
        ssm := make([]string, 10, 10)
        fmt.Printf("int slice make [%p] init value: %v, len:%d, cap:%d
    ", &sim, sim, len(sim), cap(sim))
        fmt.Printf("string slice make [%p] init value: %v, len:%d, cap:%d
    ", &ssm, ssm, len(ssm), cap(ssm))
        fmt.Println("---------------------------------------")
    
        for i = 0; i < len(sim); i++ {
            sim[i] = 100 + i
        }
        for i,_ := range ssm {
            ssm[i] = strconv.Itoa(100+i)
        }
        fmt.Printf("int slice make [%p] init value: %v, len:%d, cap:%d
    ", &sim, sim, len(sim), cap(sim))
        fmt.Printf("string slice make [%p] init value: %v, len:%d, cap:%d
    ", &ssm, ssm, len(ssm), cap(ssm))
        fmt.Println("---------------------------------------")
    
    //    fmt.Printf("%v
    ==
    %v
    ???
    %t
    ", si, *psi, (si==*psi))
        fmt.Println("---------------------------------------")
    //    fmt.Printf("%v
    ==
    %v
    ???
    %t
    ", ss, ssm, (ss==ssm))
    
    }

    运行结果:

    int slice [0xc00006a020] init value: [], len:0, cap:0
    string slice [0xc00006a040] init value: [], len:0, cap:0
    ---------------------------------------
    int slice [0xc00006a020] append 0 element: [100], len:1, cap:1
    int slice [0xc00006a020] append 1 element: [100 101], len:2, cap:2
    int slice [0xc00006a020] append 2 element: [100 101 102], len:3, cap:4
    int slice [0xc00006a020] append 3 element: [100 101 102 103], len:4, cap:4
    int slice [0xc00006a020] append 4 element: [100 101 102 103 104], len:5, cap:8
    int slice [0xc00006a020] append 5 element: [100 101 102 103 104 105], len:6, cap:8
    int slice [0xc00006a020] append 6 element: [100 101 102 103 104 105 106], len:7, cap:8
    int slice [0xc00006a020] append 7 element: [100 101 102 103 104 105 106 107], len:8, cap:8
    int slice [0xc00006a020] append 8 element: [100 101 102 103 104 105 106 107 108], len:9, cap:16
    int slice [0xc00006a020] append 9 element: [100 101 102 103 104 105 106 107 108 109], len:10, cap:16
    ---------------------------------------
    string slice [0xc00006a040] append 0 element: [100], len:1, cap:1
    string slice [0xc00006a040] append 1 element: [100 101], len:2, cap:2
    string slice [0xc00006a040] append 2 element: [100 101 102], len:3, cap:4
    string slice [0xc00006a040] append 3 element: [100 101 102 103], len:4, cap:4
    string slice [0xc00006a040] append 4 element: [100 101 102 103 104], len:5, cap:8
    string slice [0xc00006a040] append 5 element: [100 101 102 103 104 105], len:6, cap:8
    string slice [0xc00006a040] append 6 element: [100 101 102 103 104 105 106], len:7, cap:8
    string slice [0xc00006a040] append 7 element: [100 101 102 103 104 105 106 107], len:8, cap:8
    string slice [0xc00006a040] append 8 element: [100 101 102 103 104 105 106 107 108], len:9, cap:16
    string slice [0xc00006a040] append 9 element: [100 101 102 103 104 105 106 107 108 109], len:10, cap:16
    ---------------------------------------
    int slice pointer [0xc00007e020] init value: <nil>
    string slice pointer [0xc00007e028] init value: <nil>
    ---------------------------------------
    int slice pointer [0xc00007e020] init value: [100 101 102 103 104 105 106 107 108 109], len:10, cap:16
    string slice pointer [0xc00007e028] init value: [100 101 102 103 104 105 106 107 108 109], len:10, cap:16
    ---------------------------------------
    int slice make [0xc00006a340] init value: [0 0 0 0 0 0 0 0 0 0], len:10, cap:10
    string slice make [0xc00006a360] init value: [         ], len:10, cap:10
    ---------------------------------------
    int slice make [0xc00006a340] init value: [100 101 102 103 104 105 106 107 108 109], len:10, cap:10
    string slice make [0xc00006a360] init value: [100 101 102 103 104 105 106 107 108 109], len:10, cap:10
    ---------------------------------------
    ---------------------------------------

    4. map

    Map是引用类型当 map 被赋值为一个新变量的时候,它们指向同一个内部数据结构。因此,改变其中一个变量,就会影响到另一变量。

    map的零值是nil,不能插入元素。map没有容量的概念,其长度为目前元素的个数。

    只要map不为nil就可以无限插入元素。“map[]=”插入元素。

    map实体初始化为nil。需要make()或“=map[int]int{}”进行初始化后才能加元素。

    map指针初始化为nil

    make返回类型零值的map,且长度为0,无论make中是否指定len或指定len大小。

    map只能和nil作比较。要比较map,需比较两个map的每个元素。

    package main
    
    import (
        "fmt"
        "strconv"
    )
    
    func main(){
        var mi map[int]int
        var ms map[string]string
        fmt.Printf("int map [%p] init value: %v, len:%d
    ", &mi, mi, len(mi))
        fmt.Printf("string map [%p] init value: %v, len:%d
    ", &ms, ms, len(ms))
        fmt.Println("-------------------------------")
    
        var i int
        if mi == nil {
            mi = make(map[int]int)
            fmt.Printf("int map make [%p] init value: %v, len:%d
    ", &mi, mi, len(mi))
            for i = 0; i < 10; i++ {
                mi[i] = 100 + i
                fmt.Printf("int map make [%p] init %d value: %v, len:%d
    ", &mi, i, mi, len(mi))
            } 
        }
        fmt.Println("-------------------------------")
    
        if ms == nil {
            ms = make(map[string]string, 10)
            fmt.Printf("string map make [%p] init value: %v, len:%d
    ", &ms, ms, len(ms))
            for i = 0; i < 10; i++ {
                k := strconv.Itoa(100+i)    
                ms[k] = strconv.Itoa(100+i)
                fmt.Printf("string map make [%p] init [%v] value: %v, len:%d
    ", &ms, k, ms, len(ms))
            }
        }
        fmt.Println("-------------------------------")
    
        var pmi *map[int]int
        var pms *map[string]string
    //    fmt.Printf("int map pointer [%p] init value: %v, len:%d
    ", &pmi, pmi, len(*pmi))
    //    fmt.Printf("string map pointer [%p] init value: %v, len:%d
    ", &pms, pms, len(*pms))
        fmt.Printf("int map pointer [%p] init value: %v
    ", &pmi, pmi)
        fmt.Printf("string map pointer [%p] init value: %v
    ", &pms, pms)
        fmt.Println("-------------------------------")
    
        pmi = &mi
        pms = &ms
        fmt.Printf("int map pointer [%p] init value: %v, len:%d
    ", &pmi, pmi, len(*pmi))
        fmt.Printf("string map pointer [%p] init value: %v, len:%d
    ", &pms, pms, len(*pms))
        fmt.Println("-------------------------------")
    
    //    fmt.Printf("%v
    ==%v
    ???
    %t
    ", mi, *pmi, (mi==*pmi))
        fmt.Println("-------------------------------")
    //    fmt.Printf("%v
    ==%v
    ???
    %t
    ", ms, *pms, (ms==*pms))
    
        var mii map[int]int = map[int]int{}
        var mss map[string]string = map[string]string{}
        fmt.Printf("int map [%p] init value: %v, len:%d
    ", &mii, mii, len(mii))
        fmt.Printf("string map [%p] init value: %v, len:%d
    ", &mss, mss, len(mss))
        fmt.Println("-------------------------------")
    
        for i = 0; i < 10; i++ {
            mii[i] = 100 + i
        } 
    
        for i = 0; i < 10; i++ {
            k := strconv.Itoa(100+i)    
            mss[k] = strconv.Itoa(100+i)
        }
        fmt.Printf("int map [%p] init value: %v, len:%d
    ", &mii, mii, len(mii))
        fmt.Printf("string map [%p] init value: %v, len:%d
    ", &mss, mss, len(mss))
        fmt.Println("-------------------------------")
    }

    运行结果:

    int map [0xc00007e018] init value: map[], len:0
    string map [0xc00007e020] init value: map[], len:0
    -------------------------------
    int map make [0xc00007e018] init value: map[], len:0
    int map make [0xc00007e018] init 0 value: map[0:100], len:1
    int map make [0xc00007e018] init 1 value: map[0:100 1:101], len:2
    int map make [0xc00007e018] init 2 value: map[0:100 1:101 2:102], len:3
    int map make [0xc00007e018] init 3 value: map[0:100 1:101 2:102 3:103], len:4
    int map make [0xc00007e018] init 4 value: map[0:100 1:101 2:102 3:103 4:104], len:5
    int map make [0xc00007e018] init 5 value: map[0:100 1:101 2:102 3:103 4:104 5:105], len:6
    int map make [0xc00007e018] init 6 value: map[0:100 1:101 2:102 3:103 4:104 5:105 6:106], len:7
    int map make [0xc00007e018] init 7 value: map[0:100 1:101 2:102 3:103 4:104 5:105 6:106 7:107], len:8
    int map make [0xc00007e018] init 8 value: map[0:100 1:101 2:102 3:103 4:104 5:105 6:106 7:107 8:108], len:9
    int map make [0xc00007e018] init 9 value: map[0:100 1:101 2:102 3:103 4:104 5:105 6:106 7:107 8:108 9:109], len:10
    -------------------------------
    string map make [0xc00007e020] init value: map[], len:0
    string map make [0xc00007e020] init [100] value: map[100:100], len:1
    string map make [0xc00007e020] init [101] value: map[100:100 101:101], len:2
    string map make [0xc00007e020] init [102] value: map[100:100 101:101 102:102], len:3
    string map make [0xc00007e020] init [103] value: map[100:100 101:101 102:102 103:103], len:4
    string map make [0xc00007e020] init [104] value: map[100:100 101:101 102:102 103:103 104:104], len:5
    string map make [0xc00007e020] init [105] value: map[100:100 101:101 102:102 103:103 104:104 105:105], len:6
    string map make [0xc00007e020] init [106] value: map[100:100 101:101 102:102 103:103 104:104 105:105 106:106], len:7
    string map make [0xc00007e020] init [107] value: map[100:100 101:101 102:102 103:103 104:104 105:105 106:106 107:107], len:8
    string map make [0xc00007e020] init [108] value: map[100:100 101:101 102:102 103:103 104:104 105:105 106:106 107:107 108:108], len:9
    string map make [0xc00007e020] init [109] value: map[100:100 101:101 102:102 103:103 104:104 105:105 106:106 107:107 108:108 109:109], len:10
    -------------------------------
    int map pointer [0xc00007e030] init value: <nil>
    string map pointer [0xc00007e038] init value: <nil>
    -------------------------------
    int map pointer [0xc00007e030] init value: &map[0:100 1:101 2:102 3:103 4:104 5:105 6:106 7:107 8:108 9:109], len:10
    string map pointer [0xc00007e038] init value: &map[100:100 101:101 102:102 103:103 104:104 105:105 106:106 107:107 108:108 109:109], len:10
    -------------------------------
    -------------------------------
    int map [0xc00007e040] init value: map[], len:0
    string map [0xc00007e048] init value: map[], len:0
    -------------------------------
    int map [0xc00007e040] init value: map[0:100 1:101 2:102 3:103 4:104 5:105 6:106 7:107 8:108 9:109], len:10
    string map [0xc00007e048] init value: map[100:100 101:101 102:102 103:103 104:104 105:105 106:106 107:107 108:108 109:109], len:10
    -------------------------------

    5. struct

    结构体是值类型,可以直接用=赋值。

    结构体实体初始化为每个成员的零值,仅为某些字段指定初始值时,忽略的字段会赋值为零值。

    结构体指针值为nil

    new()返回指向类型零值的指针。

    如果它的每一个字段都是可比较的,则该结构体也是可比较的。如果两个结构体变量的对应字段相等,则这两个变量也是相等的。如果结构体包含不可比较的字段,则结构体变量也不可比较。

    map可以以指针和实体方式返回,函数返回后可以通过返回值访问到原来函数内部的结构体(即函数内部的结构体不会随着函数结束而被回收)。

    package main
    
    import (
        "fmt"
    )
    
    type People struct {
        Name string 
        Phone string
        Addr []string
    }
    
    func main(){
        var pStruct People
    //    if pStruct == nil {
    //        fmt.Println("var initvalue is null")
    //    } else {
            fmt.Println("var initvalue init: ",pStruct)
            fmt.Println("var initvalue init: Name: ", pStruct.Name)
            fmt.Println("var initvalue init: Name: ", pStruct.Phone)
            fmt.Println("var initvalue init: Name: ", pStruct.Addr, ", len:", len(pStruct.Addr))
            pStruct =  People{"wang", "123456", []string{"Beijing", "Shanghai"}}    
            fmt.Println("after var initvalue init: ", pStruct)
    //    }
        fmt.Println("-------------------------------------------")
    
        var p *People
        if p == nil {
            fmt.Println("pointer initvalue is null")
        } else {
            fmt.Println("pointer initvalue is ", p)
        } 
    
        fmt.Println("-------------------------------------------")
        peo := new(People)
        if peo == nil {
            fmt.Println("new struct initvalue is null")
        } else {
            fmt.Println("new struct initvalue is ", peo)
            peo.Name = "wang"
            peo.Phone = "123456"
            fmt.Println("after new struct initvalue is ", peo)
        }
        fmt.Println("-------------------------------------------")
    
        tmp, _ := testReturn() 
        fmt.Printf("return [%p] value: %v
    ", &tmp, tmp)
        fmt.Println("-------------------------------------------")
    
        ptmp, _ := testReturnPointer() 
        fmt.Printf("return pointer [%p]:[%p] value: %v
    ", &ptmp, ptmp, *ptmp)
        fmt.Println("-------------------------------------------")
    }
    func testReturnPointer()(*People, error){
        tmp := People{} 
        tmp.Name = "wang"
        tmp.Phone = "123"
        fmt.Printf("In function, return pointer [%p] value: %v
    ", &tmp, tmp)
        return &tmp, nil
    }
    
    func testReturn()(People, error){
        tmp := People{} 
        tmp.Name = "wang"
        tmp.Phone = "123"
        fmt.Printf("In function, return [%p] value: %v
    ", &tmp, tmp)
        return tmp, nil
    }

    运行结果:

    var initvalue init:  {  []}
    var initvalue init: Name:
    var initvalue init: Name:
    var initvalue init: Name:  [] , len: 0
    after var initvalue init:  {wang 123456 [Beijing Shanghai]}
    -------------------------------------------
    pointer initvalue is null
    -------------------------------------------
    new struct initvalue is  &{  []}
    after new struct initvalue is  &{wang 123456 []}
    -------------------------------------------
    In function, return [0xc0000841c0] value: {wang 123 []}
    return [0xc000084180] value: {wang 123 []}
    -------------------------------------------
    In function, return pointer [0xc000084280] value: {wang 123 []}
    return pointer [0xc00007e020]:[0xc000084280] value: {wang 123 []}
    -------------------------------------------
  • 相关阅读:
    27 Spring Cloud Feign整合Hystrix实现容错处理
    26 Spring Cloud使用Hystrix实现容错处理
    25 Spring Cloud Hystrix缓存与合并请求
    24 Spring Cloud Hystrix资源隔离策略(线程、信号量)
    23 Spring Cloud Hystrix(熔断器)介绍及使用
    22 Spring Cloud Feign的自定义配置及使用
    21 Spring Cloud使用Feign调用服务接口
    20 Spring Cloud Ribbon配置详解
    19 Spring Cloud Ribbon自定义负载均衡策略
    18 Spring Cloud Ribbon负载均衡策略介绍
  • 原文地址:https://www.cnblogs.com/embedded-linux/p/12006394.html
Copyright © 2011-2022 走看看