Golang基础语法(3)

51 阅读3分钟

14 结构体

//类型定义,NewInt就是拥有int属性的另一种类型
type NewInt int//类型别名,MyInt本质就是int
type MyInt = intfunc 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 倍容量重新分配底层数组。