Golang基础-5

admin2024-04-03  3

Go语言基础

介绍

基础

  • 切片
    • 切片声明
    • 切片初始化
    • 切片基础操作
    • 多维切片

介绍

  • 本文介绍Go语言中切片(slice)(切片声明、切片初始化、切片基础操作、多维切片)等相关知识。

基础

切片
  • 切片(slice)是对数组的一个连续片段的引用,切片是一个引用类型。
  • 切片是长度可变的数组,由三部分组成:
    • 指针:指向的数组元素的地址
    • 长度:元素的数量
    • 容量:切片可容纳多少元素
切片声明
  • 需要指定组成元素的类型,不需要指定存储元素的个数。
  • 声明后,默认初始化为 nil,意思是不存在此切片引用。
package main

import "fmt"

func main() {
	// 声明一个切片
	var slice1 []int
	fmt.Printf("slice1 type: %T, value: %v\n", slice1, slice1)
	// 自动类型推导
	slice2 := []int{}
	fmt.Printf("slice2 type: %T, value: %v\n", slice2, slice2)
}
切片初始化
  • 切片初始化方式较多,具体如下
package main

import "fmt"

func main() {
	// 字面量初始化
	var slice1 []int = []int{1, 2, 3, 4, 5}
	fmt.Println("slice1: ", slice1, ", cap: ", cap(slice1))
	// 字面量初始化空切片
	var slice2 []int = []int{}
	fmt.Println("slice2: ", slice2, ", cap: ", cap(slice2))
	// 从数组创建并初始化切片
	var arr [5]int = [5]int{1, 2, 3, 4, 5}
	slice3 := arr[0:3]
	fmt.Println("slice3: ", slice3, ", cap: ", cap(slice3))
	slice4 := arr[0:2:2]
	fmt.Println("slice4: ", slice4, ", cap: ", cap(slice4))
	// 从切片创建并初始化切片
	slice5 := slice4[:1]
	fmt.Println("slice5: ", slice5, ", cap: ", cap(slice5))
	slice6 := slice4[1:]
	fmt.Println("slice6: ", slice6, ", cap: ", cap(slice6))
	slice7 := slice4[:]
	fmt.Println("slice7: ", slice7, ", cap: ", cap(slice7))
	slice8 := slice4[0:0]
	fmt.Println("slice8: ", slice8, ", cap: ", cap(slice8))
	// 指定长度和容量字面量初始化
	slice9 := []int{0: 20, 4: 60}
	fmt.Println("slice9: ", slice9, ", cap: ", cap(slice9))
	// 使用 make 函数初始化
	slice10 := make([]int, 3)
	fmt.Println("slice10: ", slice10, ", cap: ", cap(slice10))
	slice11 := make([]int, 3, 6)
	fmt.Println("slice11: ", slice11, ", cap: ", cap(slice11))
}
切片基础操作
  • 获取切片长度和容量
package main

import "fmt"

func main() {
	var slice1 []int = []int{1, 2, 3, 4, 5}
	fmt.Printf("slice1 len: %v, cap: %v\n", len(slice1), cap(slice1))
}
  • 切片的访问和修改(通过索引对切片元素进行访问和修改,元素的索引从左到右依次为:0 ~ n(n为切片长度-1))
  • 切片共享底层数组,任何变化都会导致其它切片及底层共享数组变化
package main

import "fmt"

func main() {
	// 以数组方式创建切片
	var arr [5]int = [5]int{1, 2, 3, 4, 5}
	fmt.Printf("arr : %v\n", arr)
	var slice1 []int = arr[0:3]
	fmt.Printf("slice1 : %v\n", slice1)

	// 索引方式访问
	fmt.Printf("slice1[0] : %v\n", slice1[0])
	fmt.Printf("slice1[1] : %v\n", slice1[1])
	fmt.Printf("slice1[2] : %v\n", slice1[2])

	// 修改值
	slice1[0] = 100
	slice1[2] = 200
	fmt.Printf("slice1 : %v\n", slice1)
	fmt.Printf("arr : %v\n", arr)

    // 切片创建新切片
	slice2 := slice1[:] 
	fmt.Printf("slice2 : %v\n", slice2)
	slice2[0] = 150
	slice2[1] = 230
	fmt.Printf("slice2 : %v\n", slice2)
	fmt.Printf("slice1 : %v\n", slice1)
	fmt.Printf("arr : %v\n", arr)
}
  • 切片遍历
package main

import "fmt"

func main() {
	var arr [5]int = [5]int{1, 2, 3, 4, 5}
	fmt.Printf("arr : %v\n", arr)
	var slice1 []int = arr[0:3]
	fmt.Printf("slice1 : %v\n", slice1)

	// for 循环方式遍历
	for i := 0; i < len(slice1); i++ {
		fmt.Println("slice1[", i, "] = ", slice1[i])
	}

	fmt.Println("======================")
	// for-range 方式遍历
	for i, v := range slice1 {
		fmt.Println("slice1[", i, "] = ", v)
	}
}
  • 增加元素,内建函数 append 可以为切片动态添加元素
  • 使用 append 对切片增加元素并返回修改后切片
  • 当长度len在容量cap范围内时只增加长度,容量和底层数组不变;当长度len超过容量cap范围则会新创建底层数组并对容量进行扩容
  • 元素数量小于 1024 时,约按原容量 1 倍增加,元素数量大于 1024 时约按原容量 0.5 倍增加(不同Go版本可能有变化,当前使用Go1.22)
  • 切片头部增加元素会导致切片整体复制操作,效率没有末尾增加元素高
package main

import "fmt"

func main() {
	var arr [5]int = [5]int{1, 2, 3, 4, 5}
	fmt.Printf("arr : %v\n", arr)
	var slice1 []int = arr[0:3]
	fmt.Printf("slice1 : %v, len: %v, cap: %v\n", slice1, len(slice1), cap(slice1))

	// 增加元素,末尾增加
	slice1 = append(slice1, 100, 200, 300)
	fmt.Printf("slice1 append: %v, len: %v, cap: %v\n", slice1, len(slice1), cap(slice1))

	// 增加元素,末尾增加
	slice1 = append(slice1, 1, 2, 3, 4, 5, 6, 7, 8)
	fmt.Printf("slice1 append: %v, len: %v, cap: %v\n", slice1, len(slice1), cap(slice1))

	slice2 := []int{0: 100, 1023: 100}
	fmt.Printf("slice2 len: %v, cap: %v\n", len(slice2), cap(slice2))
	// 增加超过 1024 个元素,末尾增加
	slice2 = append(slice2, 1, 2, 3, 4, 5)
	fmt.Printf("slice2 len: %v, cap: %v\n", len(slice2), cap(slice2))
}

  • 切片复制,使用 copy 函数,复制元素数量为 src 元素数量和 dest 元素数量的最小值
package main

import "fmt"

func main() {

	var slice1 []int = []int{1, 2, 3}
	var slice2 []int = []int{100, 200, 300, 400, 500}
	var slice3 []int = []int{1}

    // copy slice2的3个元素替换到slice1元素
	copy(slice1, slice2)
	fmt.Printf("%v, %v, %v\n", slice1, slice2, slice3)

    // copy slice3的1个元素替换到slice2的第一个元素
	copy(slice2, slice3)
	fmt.Printf("%v, %v, %v\n", slice1, slice2, slice3)

    // copy slice1的1个元素替换到slice3的第一个元素
	copy(slice3, slice1)
	fmt.Printf("%v, %v, %v\n", slice1, slice2, slice3)
}
  • 删除元素,清空切片
package main

import "fmt"

func main() {
	var slice1 []int = []int{1, 2, 3}

	// 清空切片
	slice1 = slice1[0:0]
	fmt.Println("slice1 clear: ", slice1)

	slice1 = append(slice1, 1, 2, 3, 4, 5, 6)
	fmt.Println("slice1 append: ", slice1)

	// 清空切片
	slice1 = nil
	fmt.Println("slice1 clear: ", slice1)

	slice1 = append(slice1, 1, 2, 3, 4, 5, 6)
	fmt.Println("slice1 append: ", slice1)

	// 删除切片,删除第一个元素
	slice1 = slice1[1:]
	fmt.Println(slice1)

	// 增加第一个元素(将上一步删除的元素重新添加到原来位置)
	slice1 = append([]int{1}, slice1...)
	fmt.Println("slice1 append: ", slice1)

	// 删除切片,删除末尾元素
	slice1 = slice1[:len(slice1)-1]
	fmt.Println(slice1)

	// 增加末尾的元素
	slice1 = append(slice1, 6)
	fmt.Println("slice1 append: ", slice1)

	// 删除第三个元素
	slice3 := []int{}
	slice3 = append(slice3, slice1[0:2]...)
	slice3 = append(slice3, slice1[3:]...)
	slice1 = slice3
	fmt.Println("slice3: ", slice1)
}
多维切片
  • 多维切片即切片的元素也可以是切片类型
package main

import "fmt"

func main() {
	// 二维切片声明且初始化
	var slice1 [][]int = [][]int{{1, 2, 3}, {4, 5, 66}}
	fmt.Println("slice1: ", slice1)
	// 自动类型推导
	slice2 := [][]int{{1, 2, 3}, {4, 55, 6}}
	fmt.Println("slice2: ", slice2)

	// make创建切片
	slice3 := make([][]int, 2)
	fmt.Println("slice3: ", slice3)
	slice4 := make([][]int, 2, 5)
	fmt.Println("slice4: ", slice4)

	// 修改与访问
	slice2[0] = []int{100, 200, 300, 400}
	slice2[0][2] = 30
	fmt.Println("slice2: ", slice2)

	// 切片创建切片
	fmt.Println("slice3: ", slice2[0:1])

	// 切片遍历,for 循环
	for i := 0; i < len(slice2); i++ {
		for j := 0; j < len(slice2[i]); j++ {
			fmt.Printf("slice2[%v][%v] = %v\t", i, j, slice2[i][j])
		}
		fmt.Println()
	}
	// 切片遍历,for-range
	for i, s := range slice2 {
		for j, v := range s {
			fmt.Printf("slice2[%v][%v] = %v\t", i, j, v)
		}
		fmt.Println()
	}

	// 增加元素
	slice1 = append(slice1, []int{10, 20, 30, 40})
	fmt.Println("slice1 append: ", slice1)
	slice1[0] = append(slice1[0], 10, 20, 30, 40)
	fmt.Println("slice1 append: ", slice1)

	// 复制元素,src 数量少于 dst 数量时,将 src 对应行替换到 dst对应行,dst 多出行继续显示
	// src 数量大于 dst 数量时,以 dst 数量为准,将 src 对应行替换到 dst对应行
	fmt.Println("slice1 copy before: ", slice1)
	fmt.Println("slice2 copy before: ", slice2)
	copy(slice1, slice2)
	fmt.Println("slice1 copy: ", slice1)
}

起始

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明原文出处。如若内容造成侵权/违法违规/事实不符,请联系SD编程学习网:675289112@qq.com进行投诉反馈,一经查实,立即删除!