数组
package main
import (
"fmt"
)
func main() {
// 数组初始化方式
var a [3]int
fmt.Println(a) // 定义长度为3的int型数组, 元素全部为0
var a2 = [3]int{1, 2, 4}
fmt.Println(a2) // 定义长度为3的int型数组, 元素为 1, 2, 4
var a3 = [...]int{1: 3, 2: 2}
fmt.Println(a3); // 定义长度为3的int型数组, 元素为 0, 3, 2
//注释1:3 表示在1的位置设置3,1位前没有数据补0
var a4 = [...]int{1, 2, 4: 5, 6}
fmt.Println(a4) // 定义长度为6的int型数组, 元素为 1, 2, 0, 0, 5, 6
a5 := [...]int{1, 2, 4: 5, 6}
fmt.Println(a5) // 定义长度为6的int型数组, 元素为 1, 2, 0, 0, 5, 6
// 数组访问方式
for i := 0; i < 3; i++ {
fmt.Printf("%v ", a2[i])
}
fmt.Printf("\n")
for i := range a4 {
fmt.Printf("%v ", i)
}
fmt.Printf("\n")
for i, v := range a4 {
fmt.Printf("b[%d]: %d\n", i, v)
}
// 函数调用数组
var ptr *[3]int;
ptr = &a2;
fmt.Printf("a 变量的地址是: %x\n", &ptr) //c000080020
display(a2)
}
func display(data [3]int) {
var ptr *[3]int;
ptr = &data;
fmt.Printf("data 变量的地址是: %x\n", &ptr) //c000080028
fmt.Println(data)
//一个数组变量即表示整个数组,它并不是隐式的指向第一个元素的指针(比如C语言的数组),而是一个完整的值
}
字符串 : 字符串的元素不可修改,是一个只读的字节数组
注:Go语言除了for range语法对UTF8字符串提供了特殊支持外,还对字符串和[]rune类型的相互转换提供了特殊的支持
底层结构
type StringHeader struct {
Data uintptr
Len int
}
package main
import "fmt"
func main() {
s := "hello, world"
hello := s[:5]
world := s[7:]
s1 := "hello, world"[:5]
s2 := "hello, world"[7:]
fmt.Println(s, hello, world, s1, s2)
fmt.Printf("%#v\n", []byte("Hello, 世界")) //[]byte{0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0xe4, 0xb8, 0x96, 0xe7, 0x95, 0x8c}
fmt.Printf("%v\n", []byte("Hello, 世界")) //[72 101 108 108 111 44 32 228 184 150 231 149 140]
fmt.Printf("%v\n", ("Hello, 世界")) //Hello, 世界
}
切片
底层结构
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
package main
import "fmt"
func main() {
var s1 []int // nil切片, 和 nil 相等, 一般用来表示一个不存在的切片
fmt.Println(s1)
var s2 = []int{}
fmt.Println(s2) // 空切片, 和 nil 不相等, 一般用来表示一个空的集合
var s3 = []int{1, 2, 3}
fmt.Println(s3); // 有3个元素的切片, len和cap都为3
var s4 = s3[:2]
fmt.Println(s4) // 有2个元素的切片, len为2, cap为3
var s5 = s3[0:2:cap(s3)]
fmt.Println(s5) // 有2个元素的切片, len为2, cap为3
var s6 = make([]int, 3)
fmt.Println(s6) // 有3个元素的切片, len和cap都为3
var s7 = make([]int, 2, 3)
fmt.Println(s7) // 有2个元素的切片, len为2, cap为3
// 遍历切片
for i := range s3 {
fmt.Printf("a[%d]: %d\n", i, s3[i])
}
for i, v := range s3 {
fmt.Printf("b[%d]: %d\n", i, v)
}
for i := 0; i < len(s3); i++ {
fmt.Printf("c[%d]: %d\n", i, s3[i])
}
var a = []int{}
//添加切片数据
a = append(a, 1)
a = append(a, 2, 3)
a = append(a, []int{4, 5}...)
a = append([]int{-1, 0}, a...)
fmt.Println(a)
a = append(a[:2], append([]int{-2}, a[2:]...)...)
fmt.Println(a)
fmt.Println(copy(a[2:], a[1:]))
a[1] = 9
fmt.Println(a)
//没有专门的内置函数用于扩展切片的容量,append本质是用于追加元素而不是扩展容量,扩展切片容量只是append的一个副作用
//删除切片数据
a = a[2:]
a = a[:len(a)-2]
fmt.Println(a)
a = append(a[:1], a[2:]...)
fmt.Println(a)
a = a[:1+copy(a[1:], a[1+1:])]
fmt.Println(a)
}