Go 中为什么切片不用初始化就可以使用 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成内容
xmge
V2EX    程序员

Go 中为什么切片不用初始化就可以使用

  •  
  • &nbs; xmge 2020-03-23 08:59:03 +08:00 5930 次点击
    这是一个创建于 2029 天前的主题,其中的信息可能已经有所发展或是发生改变。
    package main import ( "fmt" ) func main() { // 可以使用 var s []string s = append(s, "a") fmt.Println(s) // 未初始化不可使用 var m map[string]string m["a"]= "b" fmt.Println(m) // 未初始化不可使用 var c chan string go func() { fmt.Println(<-c) }() c <- "a" } 
    第 1 条附言    2020-03-23 09:51:46 +08:00
    1 、s[0] = "a" 会报错,所以 append 之前 slice 并不可使用,应该是 apend 时进行了初始化
    2 、0 切片,nli 切片,空切片的概念: http://www.meirixz.com/archives/80658.html

    v2 大佬就是多,解决问题就是快。感谢大佬。
    如果上面的解释有什么问题,欢迎大佬指出,或则有什么更容易理解的说法,也请赐教。
    第 2 条附言    2020-03-23 10:11:21 +08:00
    append 函数源码中的注释:

    ```
    // The append built-in function appends elements to the end of a slice. If
    // it has sufficient capacity, the destination is resliced to accommodate the
    // new elements. If it does not, a new underlying array will be allocated.
    // Append returns the updated slice. It is therefore necessary to store the
    // result of append, often in the variable holding the slice itself:
    // slice = append(slice, elem1, elem2)
    // slice = append(slice, anotherSlice...)
    // As a special case, it is legal to append a string to a byte slice, like this:
    // slice = append([]byte("hello "), "world"...)
    func append(slice []Type, elems ...Type) []Type
    ```
    17 条回复    2020-03-23 17:28:33 +08:00
    baiyi
        1
    baiyi  
       2020-03-23 09:26:46 +08:00
    这应该算语言特性?

    slice 在 append 调用的方法中判断了一下,如果没有初始化的底层数组指针,就新建一个。
    pennchester
        2
    pennchester  
       2020-03-23 09:37:41 +08:00
    你这样创建的是 nil 切片,切片是个特殊的引用类型,var s []string 这种声明会指向的一个为 0 的地址,你可以参考一下这篇文章
    http://www.meirixz.com/archives/80658.html
    xmge
        3
    xmge  
    OP
       2020-03-23 09:40:26 +08:00
    @baiyi 可能是吧。在 append 之前调用 len()或 cap()结果都是 0 。在网上搜索答案都是 make 或者显示创建来初始化,之前也一直有这疑问,但是没有深追。
    gbanbo
        4
    gbanbo  
       2020-03-23 09:43:21 +08:00
    你把 s = append(s, "a")改成 s[0] = "a"就知道了,和下面的 map 一样会 panic,append 只是帮你判断,如果是 nil 就帮你 make 了。
    xmge
        5
    xmge  
    OP
       
    @gbanbo @pennchester 好的,感谢大佬 ~\()/~
    pennchester
        6
    pennchester  
       2020-03-23 10:00:12 +08:00
    @gbanbo 其实你这个不是很准确,你这个会报错是因为越界了,你用 make 产生的切片,容量设为 0,同样会报错的
    ty4z2008
        7
    ty4z2008  
       2020-03-23 10:02:44 +08:00
    https://blog.golang.org/slices-intro

    这个是因为 append 内部实现了 slice 的自增。与此类似的函数还有 copy 。这两个函数内部都进行 make 初始化。每次对 slice 的操作内部是会产生一个新的数组,然后返回
    janxin
        8
    janxin  
       2020-03-23 10:03:17 +08:00
    其实你这个疑问可以跑个程序输出一下就明白了

    https://play.golang.org/p/e6TsC_5Jk_B
    l1905
        9
    l1905  
       2020-03-23 10:04:40 +08:00
    先看下 append 的定义, 是先判断 cap, 长度不够, 直接 copy 出为新 slice
    https://blog.golang.org/slices-intro

    https://gist.github.com/l1905/424f15d629ee0dcdb5c4727c0c83559a
    xmge
        10
    xmge  
    OP
       2020-03-23 10:12:49 +08:00
    @ty4z2008 @janxin @l1905 感谢大佬~\()/~
    mengzhuo
        11
    mengzhuo  
       2020-03-23 10:13:34 +08:00
    append 的语法糖
    reus
        12
    reus  
       2020-03-23 10:50:09 +08:00
    /div>
    append 会初始化 nil slice,而 map 和 chan 就没有 append 函数去做这个事情
    你的代码里,slice 的“使用”是调用了函数的,而 map 和 chan 就没有
    fcten
        13
    fcten  
       2020-03-23 11:00:56 +08:00
    说 append 会初始化是不准确的,其实 append 直接返回了一个新的 slice 给你
    lcj2class
        14
    lcj2class  
       2020-03-23 11:13:36 +08:00
    go tool compile -S xx.go
    编译看下就知道了,会调用 runtime.growslice 来创建一个。
    123444a
        15
    123444a  
       2020-03-23 15:46:38 +08:00 via Android
    append 这么简单的定义,看来你开始是理解错了
    epson3333
        16
    epson3333  
       2020-03-23 16:49:46 +08:00
    老哥啥时候发多个政治贴
    xmge
        17
    xmge  
    OP
       2020-03-23 17:28:33 +08:00
    @epson3333 ??? 没听明白
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2823 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 00:22 PVG 08:22 LAX 17:22 JFK 20:22
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86