美文网首页Go语言用例Go知识库
golang slice/map/chan的初始化

golang slice/map/chan的初始化

作者: CodingCode | 来源:发表于2018-04-20 14:04 被阅读16次

    我们知道make函数用来初始化slice,map,以及chan;而一个slice,map,以及chan必须先被初始化才能使用的

    先看一个slice的使用例子:

         1  package main
         2
         3  import (
         4      "fmt"
         5  )
         6
         7  func main() {
         8      var s []string
         9      fmt.Printf("len=%d cap=%d, %v\n", len(s), cap(s), s)
        10
        11      s = append(s, "aaa")
        12      fmt.Printf("len=%d cap=%d, %v\n", len(s), cap(s), s)
        13  }
    

    你觉得这个程序能不能运行?

    $ go build && ./main    
    len=0 cap=0, []
    len=1 cap=1, [aaa]
    

    有没有一点点诧异:变量s只是声明了一个slice类型,并没有进行初始化(make),这就直接被访问使用了,没有任何问题报出来,这怎么回事呢?

    答案是,声明了一个slice,而没有被初始化,那么只是表明这个slice变量的值是nil,但是这个变量的类型信息还是完美的。任何操作如果能够接受nil作为参数,那么这个操作是能够成功进行的。

    加一行代码:

         1  package main
         2
         3  import (
         4      "fmt"
         5  )
         6
         7  func main() {
         8      var s []string
         9
        10      if s == nil { fmt.Printf("s is nil\n") }
        11
        12      fmt.Printf("len=%d cap=%d, %v\n", len(s), cap(s), s)
        13
        14      s = append(s, "aaa")
        15      fmt.Printf("len=%d cap=%d, %v\n", len(s), cap(s), s)
        16  }
    

    再次运行

    $ go build && ./main    
    s is nil
    len=0 cap=0, []
    len=1 cap=1, [aaa]
    
    • 第10行,我们看到打印出来s是nil值。
    • 第12行,len()和cap()支持参数为nil的情况,返回值为0
    • 第14行,append()也接受第一个参数为nil的情况,返回一个新的slice对象。

    因为上述函数都接受nil作为参数处理,才导致这段代码正常运行。而如果碰到函数不接受nil作为输入,则必然会出错。

    如何初始化slice:
    方法1:用make

    var s1 []string = make([]string, 0)
    var s2 []string = make([]string, 1)
    var s3 []string = make([]string, 20)
    

    方法2:静态显式初始化

    var s1 []string = []string{}
    var s2 []string = []string{"aa"}
    var s3 []string = []string{"aa", "bb", "cc"}
    
    var s4 = []string{}
    var s5 = []string{"aa"}
    var s6 = []string{"aa", "bb", "cc"}
    
    s7 := []string{}
    s8 := []string{"aa"}
    s9 := []string{"aa", "bb", "cc"}
    

    需要注意的是 []string{} 这种方法,初始化成一个大小为0的slice,此时变量(s == nil)已经不成立了,但是s的大小len(s)还是等于0。实际上 []string{} == make([]string, 0)

    map和chan的概念也是一样的。

    例子1

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        var m map[string]string
    
        var n = m["AA"]
    
        fmt.Println(n)
    }
    

    编译运行

    $ go build && ./main
    
    $ 
    

    例子2

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        var m map[string]string
    
        for k, v := range m {
            fmt.Println(k, v)
        }
    }
    

    编译运行

    $ go build && ./main
    $
    

    例子3:

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        var m map[string]string
    
        m["A"] = "a"
    
        fmt.Println(len(m))
    }
    

    编译运行

    $ go build && ./main
    panic: assignment to entry in nil map
    
    goroutine 1 [running]:
    main.main()
            /.../go/src/testnew/main.go:10 +0x59
    

    在这三个例子中都定义了一个nil的map对象;而在例子1和例子2中读取map,即使map为nil,读的操作也都能成功返回,在例子3中是一个写操作,我们就可以看到写操作不允许map对象对nil,运行出错。

    相关文章

      网友评论

        本文标题:golang slice/map/chan的初始化

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