Go 语言为什么很少使用数组? - V2EX
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
frankphper

Go 语言为什么很少使用数组?

  •  
  •   frankphper Dec 31, 2023 4400 views
    This topic created in 866 days ago, the information mentioned may be changed or developed.

    大家好,我是 frank ,「 Golang 语言开发栈」公众号作者。

    01 介绍

    在 Go 语言中,数组是一块连续的内存,数组不可以扩容,数组在作为参数传递时,属于值传递。

    数组的长度和类型共同决定数组的类型,不同类型的数组之间不可以比较,否则在编译时会报错。

    因为数组的一些特性,我们在 Go 项目开发中,很少使用数组。本文我们介绍一下数组的特性。

    02 数组

    声明方式

    在 Go 语言中,数组的声明方式有三种。

    示例代码:

    func main() { var arr1 [2]int var arr2 = [2]int{1, 2} var arr3 = [...]int{1, 2} fmt.Println(arr1) fmt.Println(arr2) fmt.Println(arr3) } 

    输出结果:

    [0 0] [1 2] [1 2] 

    阅读上面这段代码,我们使用三种方式声明数组,其中 arr1arr2 的区别是,arr1 在声明时没有为数组赋值,所以输出结果是类型零值 [0 0]

    需要注意的是,arr3 没有指定数组的长度,而是使用 [...] 替代,这实际上是 Go 语言中声明数组的语法糖,编译时通过数组的赋值,自动推断数组的长度,我们可以使用内置函数 len() 查询数组的长度。

    数组的特性

    在了解嘞数组的声明方式之后,我们再来介绍一下数组具有哪些特性。

    数组的长度和类型共同决定数组的类型,例如 var arr1 [2]intvar arr2 [3]int 是不同的类型。并且不同类型的数组之间是不可以比较的,数组也不可以扩容。

    如果数组长度小于等于 4 时,在编译时会对数组做内存优化,程序启动时在栈区初始化数组,我们在使用数组类型时,也可以注意一下这一点。

    使用数组下标访问数组中的元素时,越界访问,在编译时会报错。但是,如果我们使用变量 arr[i] 作为数组下标访问数组中的元素,在编译时无法检查是否越界访问,在运行时会引发 panic

    示例代码:

    func Store() { var arr [2]int for i := 0; i < 5; i++ { arr[i] = i + 1 } fmt.Println(arr) } 

    输出结果:

    panic: runtime error: index out of range [2] with length 2 goroutine 1 [running]: ... 

    在作为参数传递数组类型的变量时,都属于值传递,我们在使用数组类型的参数时,要特别注意。

    示例代码:

    func main() { var arr2 = [2]int{1, 2} Get(arr2) fmt.Printf("arr2=%p\n%d\n", &arr2, arr2) } func Get(arr [2]int) { fmt.Printf("Get()=%p\n%d\n", &arr, arr) } 

    输出结果:

    Get()=0xc0000120f0 [1 2] arr2=0xc0000120b0 [1 2] 

    阅读上面这段代码,我们可以发现数组在作为参数传递时,地址发生变化,可以证明其属于值传递,即分配一块新内存,将数组的值拷贝到新内存。

    03 总结

    本文我们通过介绍 Go 语言中数组的一些特性,佐证数组在 Go 项目开发中很少使用的原因。

    主要原因有两点,一是数组不可以扩容;二是值传递,大数组要特别小心,如果无法避免使用大数组,可以使用数组指针。

    12 replies    2024-01-06 14:09:27 +08:00
    herozzm
        1
    herozzm  
       Dec 31, 2023
    结论就不同意,我用的挺多的
    arloor
        2
    arloor  
       Dec 31, 2023 via Android
    可以认为 slice 是 array 的门面和装饰器?
    thevita
        3
    thevita  
       Dec 31, 2023
    可以认为 slice 是一个 指向 array 的 fat-pointer
    ninjashixuan
        4
    ninjashixuan  
       Dec 31, 2023
    数组值传递也是只传递指针吧
    bthulu
        5
    bthulu  
       Dec 31, 2023
    我们组是严禁使用数组, 但凡代码里发现有数组, 就没法合进去.
    deorth
        6
    deorth  
       Dec 31, 2023 via Android
    我不同意。只要能静态长度肯定用 array 啊
    qiany
        7
    qiany  
       Dec 31, 2023
    go 不知道, java 反正是没见谁用...
    rrfeng
        8
    rrfeng  
       Dec 31, 2023 via Android
    数组是定长的,其实更像 Python 里的 tuple ,只是元素必须同类型。
    切片是可变数组,你想想哪个语言里真的会用很多定长数组的???
    prenwang
        9
    prenwang  
       Dec 31, 2023
    去看看网络协议开发的,数组无处不在, 网络协议封装那就是数组干的活, 不使用数组一看就是不专业的。 好处显而易见, 省空间,性能更好, 使用 [:] 复制为切片也很方便, 居然在项目里禁用数组,这规定也太奇葩了吧。
    sampeng
        10
    sampeng  
       Jan 1, 2024
    @prenwang 这就跟阿里云的 java 军规一个道理。先对齐颗粒度,打通底层逻辑。完全的无厘头限制。
    xuyang2
        11
    xuyang2  
       Jan 2, 2024
    @bthulu 你们的代码规范疑似有点魔怔了
    frankphper
        12
    frankphper  
    OP
       Jan 6, 2024
    @prenwang 要看使用场景,只是在大多数场景中适用。
    About     Help     Advertise     Blog     API     FAQ     Solana     1230 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 53ms UTC 17:42 PVG 01:42 LAX 10:42 JFK 13:42
    Do have faith in what you're doing.
    ubao msn 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