14 结构体
//类型定义,NewInt就是拥有int属性的另一种类型
type NewInt int
//类型别名,MyInt本质就是int
type MyInt = int
func main() {
var a NewInt
var b MyInt
fmt.Printf("type of a:%T\n", a) //type of a:main.NewInt
fmt.Printf("type of b:%T\n", b) //type of b:int
}
type person struct {
name string
age int
}
fmt.Println(person{"zqy",18}) //{123 18}
fmt.Print(person{name: "123",age: 45})
fmt.Print(person{name: "123"}) //{123 0}
//通过. 进行访问
15.切片(动态数组)
Go 语言切片是对数组的抽象.
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
如果函数进行切片传参,那么是引用传递
func test (Array []int){
}
声明
切片不需要说明长度。
1.
slice1 :=[]{xxx}
2.
或使用 make() 函数来创建切片:
var slice1 []type = make([]type, len)
slice1 = make([]type,len)
也可以简写为
//len 初始长度
3.
slice1 := make([]type, len)
也可以指定容量,其中 capacity 为可选参数。
make([]T, length, capacity)
初始化
s := arr[:]
初始化切片 s,是数组 arr 的引用。
s : = arr [startIndex:]
s : =arr [: endIndex]
len() 和 cap() 函数
切片是可索引的,并且可以由 len() 方法获取实际长度。
切片提供了计算容量的方法 cap() 可以测量切片最长可以达到多少。即可以追加的长度.(并且追加满后,底层也会动态增加上次设置的cap值)
切片截取
numbers[1:4] //左闭右开
numbers[:4] // 0 左默认
numbers[1:] // 右默认 lenth(numbers)
append和copy(切片追加和拷贝)
copy :函数 copy 在两个 slice 间复制数据,复制长度以 len 小的为准。两个 slice 可指向同一底层数组,允许元素区间重叠。
package main
import "fmt"
func main() {
var numbers []int
printSlice(numbers)
/* 允许追加空切片 */
numbers = append(numbers, 0)
printSlice(numbers)
/* 向切片添加一个元素 */
numbers = append(numbers, 1)
printSlice(numbers)
/* 同时添加多个元素 */
numbers = append(numbers, 2,3,4)
printSlice(numbers)
/* 创建切片 numbers1 是之前切片的两倍容量*/
numbers1 := make([]int, len(numbers), (cap(numbers))*2)
/* 拷贝 numbers 的内容到 numbers1 */
copy(numbers1,numbers)
printSlice(numbers1)
}
func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}
data := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
fmt.Println("array data : ", data)
s1 := data[8:]
s2 := data[:5]
fmt.Printf("slice s1 : %v\n", s1)
fmt.Printf("slice s2 : %v\n", s2)
copy(s2, s1)
fmt.Printf("slice s1 : %v\n", s1)
fmt.Printf("slice s2 : %v\n", s2)
/*
array data : [0 1 2 3 4 5 6 7 8 9]
slice s1 : [8 9]
slice s2 : [0 1 2 3 4]
slice s1 : [8 9]
slice s2 : [8 9 2 3 4]
*/
注:切片不能指定长度
arr :=[2]int{1,2} 数组并非切片
二维数组
package main
import (
"fmt"
)
func main() {
//[][]T,元素类型为[]T
data := [][]int{
[]int{1, 2, 3},
[]int{100, 200},
[]int{11, 22, 33, 44},
}
fmt.Println(data)
}
直接修改 struct array/slice 成员。
package main
import (
"fmt"
)
func main() {
d := [5]struct {
x int
}{}
s := d[:]
d[1].x = 10
//==
s[2].x = 20
fmt.Println(d)
fmt.Printf("%p, %p\n", &d, &d[0])
}
超出原 slice.cap 限制,就会重新分配底层数组,即便原数组并未填满。
package main
import (
"fmt"
)
func main() {
data := [...]int{0, 1, 2, 3, 4, 10: 0}
s := data[:2:3]
s = append(s, 100, 200) // 一次 append 两个值,超出 s.cap 限制。
fmt.Println(s, data) // 重新分配底层数组,与原数组无关。
fmt.Println(&s[0], &data[0]) // 比对底层数组起始指针。
}
/*
[0 1 100 200] [0 1 2 3 4 0 0 0 0 0 0]
0xc4200160f0 0xc420070060
*/
没有超出那么地址是一样的
通常以 2 倍容量重新分配底层数组。