golang数组和切片

数组

go语言中数据属于值类型,也就是可以直接赋值操作的,还有一种类型叫做引用类型,引用类型一般是通过指针来操作。值类型有 int/uint  字符串,bool、byte、array。引用类型有指针,结构体,通道、等等。

数组的定义

func main() {
    var list [3]int
    fmt.Println(list)
}

也可以定义的时候直接赋值

func main() {
    var list = [3]int{1, 3, 4}
    fmt.Println(list)
}

如果定义了数组没有赋值,那么值还是元素类型的零值。

数据组的一些操作

获取数组的长度

使用len关键字可以获取数组的长度,也就是数组元素的个数。

func main() {
    var list = [3]int{1, 3, 4}
    fmt.Println(len(list))
}

获取数组的容量

使用cap关键字可以获取数组的容量,

func main() {
    var list = [39]int{1, 3, 4}
    fmt.Println(cap(list))
}

获取元素

通过下标来获取某一个元素的值。

func main() {
    var list = [39]int{1, 3, 4}
    fmt.Println(list[1])
    fmt.Println(list[2])
    fmt.Println(list[3])
    fmt.Println(list[4])
}

修改元素

通过下标修改元素的值

func main() {
    var list = [39]int{1, 3, 4}
    list[1] = 100
}

数组的遍历

通过range来遍历数组。

func main() {
    var list = [39]int{1, 3, 4}
    //i is a index v is a value
    for i, v := range list {
        fmt.Println(i, v)
    }
}

 多维数组

多维数据定义的格式

func main() {
    list1 := [3][2]int{
        {1, 2},
    }
    fmt.Println(list1)
}

也可以用下面方式

func main() {
    var list1 [3][2]int
    list1[0] = [2]int{1, 2}
    fmt.Println(list1)
}
 

遍历多维数组

func main() {
    var list1 [3][2]int
    list1 = [3][2]int{
        {1, 2},
    }
    for _, k := range list1 {
        for _, j := range k {
            fmt.Println(j)
        }
    }
}

 切片 slice

切片和数组的唯一区别在于,切片的容量是可以变化的,当容量不够的时候会自动扩容,扩容的机制,是成倍扩,slice底层也是一个数组。

创建切片

类型推导方式,创建及赋值,初始化,如果没有初始化的slice是无法直接使用的

func main() {
    s1 := []int{1, 2}
    fmt.Println(s1)
}

通过make函数创建,make函数第一个参数是,需要初始化的类型,支持map chan,后面两个参数一个是长度一个是容量,下面代码表示,创建一个长度为4,容量为10 的的slice返回。


func main() {
    var s1 []int
    s1 = make([]int, 4, 10)
    fmt.Println(s1)
}
 

切片元素的操作

切片元素的操作和数组是一样的通过下标来操作,可以通过append来添加元素

添加元素

func main() {
    var s1 []int
    s1 = make([]int, 4, 10)
    s1 = append(s1, 1, 1, 1)
    fmt.Println(s1)
}

删除元素

go语言没有提供内置的函数用来删除一个slice的元素,不过通过下标操作来删除一个元素

func main() {
    var s1 []int
    s1 = make([]int, 0)
    s1 = append(s1, 1, 2, 3)
    fmt.Println(s1)
    s1 = append(s1[:1], s1[1+1:]...) //切片后面跟...表示把这个切片的元素一个一个当做参数传入
    fmt.Println(s1)
}

 范围删除

删除下标从3到5的元素

func main() {
    var s1 []int
    s1 = make([]int, 0)
    s1 = append(s1, 1, 2, 3, 5, 6, 8, 1)
    s1 = append(s1[:3], s1[6:]...)
    fmt.Println(s1)
}

 对数组切片

切片底层就是通过数组实现的,所有可以对数组切片,生成一个新的切片

func main() {
    var list = [5]int{1, 2, 3, 4, 5}
    s1 := list[1:]
    fmt.Println(s1)
    fmt.Printf("%T
", s1)
}



func main() {
    var a = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    s1 := a[:5]
    // &a表示当前整个数组a的内存地址,s1因为本身就是切片,内存中存储的内存地址,所以不需加&去获取地址了,这里获取的是s1中存储的地址
    fmt.Printf("%p,%p ", &a, s1) //内存地址是一样的
}
 

 修改地址数组对切片的影响

func main() {
    var a = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    s1 := a[:5]
    a[2] = 1000
    fmt.Println(s1)
    fmt.Println(a)
    a[9] = 10000
    fmt.Println(a)
}

修改切片对底层数组的影响

func main() {
    var a = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    s1 := a[:5]
    //把切片最后一个元素修改成100
    s1[len(s1)-1] = 100
    fmt.Println(s1)
    fmt.Println(a)
}

小总结

切片底层是一个数组实现的,所以无论你是操作底层的数组,还是切片,都将改变整个数据的值,

原文地址:https://www.cnblogs.com/Nolover/p/12510397.html