上卷 程序设计
中卷 标准库
- bufio 1.18
- bytes 1.18
- io 1.18
- container 1.18
- encoding 1.18
- crypto 1.18
- hash 1.18
- index 1.18
- sort 1.18
- context 1.18
- database 1.18
- connection
- query
- queryrow
- exec
- prepare
- transaction
- scan & null
- context
- tcp
- udp
- http
- server
- handler
- client
- h2、tls
- url
- rpc
- exec
- signal
- embed 1.18
- plugin 1.18
- reflect 1.18
- runtime 1.18
- KeepAlived
- ReadMemStats
- SetFinalizer
- Stack
- sync 1.18
- atomic
- mutex
- rwmutex
- waitgroup
- cond
- once
- map
- pool
- copycheck
- nocopy
- unsafe 1.18
- fmt 1.18
- log 1.18
- math 1.18
- time 1.18
- timer
下卷 运行时
源码剖析
附录
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
5.2 数组
数组是单一内存块,并无其他附加结构。
+---+---+---+----//---+----+ | 0 | 1 | 2 | ... ... | 99 | [100]int +---+---+---+----//---+----+
- 数组长度必须是 非负整型常量 表达式。
- 长度是数组类型组成部分。
- 初始化多维数组,仅第一维度允许用
...
。 - 初始化复合类型,可省略元素类型标签。
- 内置函数
len
和cap
都返回一维长度。 - 元素类型支持
==
、!=
,那么数组也支持。
- 支持数组指针直接访问。
- 支持获取元素指针。
- 值传递,复制整个数组。
func main() { var d1 [unsafe.Sizeof(0)]int // 编译期计算。 var d2 [2]int // 元素类型相同,长度不同! d1 = d2 ~~ cannot use [2]int as type [8]int in assignment }
灵活初始化方式。
func main() { var a [4]int // 元素自动初始化为零。 b := [4]int{2, 5} // 未提供初始值的元素自动初始化为 0。 c := [4]int{5, 3: 10} // 可指定索引位置初始化。 d := [...]int{1, 2, 3} // 编译器按初始化值数量确定数组长度。 e := [...]int{10, 3: 100} // 支持索引初始化,数组长度与此有关。 fmt.Println(a, b, c, d, e) } /* a: [0 0 0 0] b: [2 5 0 0] c: [5 0 0 10] d: [1 2 3] e: [10 0 0 100] */
func main() { type user struct { id int name string } _ = [...]user{ // 这里不能省略。 {1, "zs"}, // 元素类型标签可省略。 {2, "ls"}, } }
func main() { // var x [2]int = {2, 5} // ~~~~~~ syntax error // var y [...]int = [2]int{2, 5} // ~~~~~ invalid use of [...] array (outside a composite literal) }
多维数组依旧是连续内存存储。
func main() { x := [...][2]int{ {1, 2}, {3, 4}, } y := [...][3][2]int{ { {1, 2}, {3, 4}, {5, 6}, }, { {10, 11}, {12, 13}, {14, 15}, }, } fmt.Println(x, len(x), cap(x)) // 2, 2 fmt.Println(y, len(y), cap(y)) // 2, 2 } /* (gdb) x/4xg &x 0xc000066df0: 0x0000000000000001 0x0000000000000002 0xc000066e00: 0x0000000000000003 0x0000000000000004 (gdb) x/12xg &y 0xc000066e30: 0x0000000000000001 0x0000000000000002 0xc000066e40: 0x0000000000000003 0x0000000000000004 0xc000066e50: 0x0000000000000005 0x0000000000000006 0xc000066e60: 0x000000000000000a 0x000000000000000b 0xc000066e70: 0x000000000000000c 0x000000000000000d 0xc000066e80: 0x000000000000000e 0x000000000000000f */
相等比较,须元素支持。
func main() { var a, b [2]int println(a == b) // true c := [2]int{1, 2} d := [2]int{0, 1} println(c == d) // false // var e, f [2]map[string]int // println(e == f) // ~~~~~~ [2]map[string]int cannot be compared }
指针
注意区别不同指针及称谓。
- 数组指针:
&array
,指向整个数组的指针。 - 元素指针:
&array[0]
,指向某个元素的指针。 - 指针数组:
[...]*int{ &a, &b }
,元素是指针的数组。
func main() { d := [...]int{ 0, 1, 2, 3 } var p *[4]int = &d // 数组指针。 var pe *int = &d[1] // 元素指针。 p[0] += 10 // 相当于 (*p)[0] *pe += 20 fmt.Println(d) } // [10 21 2 3]
func main() { a, b := 1, 2 d := [...]*int{ &a, &b } // 指针数组。 *d[1] += 10 // d[1] 返回 b 指针。 fmt.Println(d) fmt.Println(a, b) } // [0xc000014080 0xc000014088] // 1 12
复制
鉴于数组传递会整个复制,可使切片或指针代替。
func val(d [3]byte) [3]byte { fmt.Printf("val: %p\n", &d) d[0] += 100 return d } func ptr(p *[3]byte) *[3]byte { fmt.Printf("ptr: %p\n", p) p[0] += 200 return p } func main() { d := [...]byte{ 1, 2, 3 } d2 := d d3 := *(&d) fmt.Printf(" d: %p\n", &d) fmt.Printf("d2: %p\n", &d2) fmt.Printf("d3: %p\n", &d3) // --------------------- d4 := val(d) fmt.Printf("val.ret: %p\n", &d4) p := ptr(&d) fmt.Printf("val.ret: %p\n", p) // --------------------- fmt.Printf("d: %v\n", d) } /* d: 0xc000014080 d2: 0xc000014083 d3: 0xc000014086 val: 0xc00001409b val.ret: 0xc000014098 ptr: 0xc000014080 val.ret: 0xc000014080 d: [201 2 3] */
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论