由浅到深认识Go语言(8):切片

该文章Github地址:https://github.com/AntonyCheng/go-notes【有条件的情况下推荐直接访问GitHub以获取最新的代码更新】

在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template【有条件的情况下推荐直接访问GitHub以获取最新的代码更新】& CSDN文章地址:https://blog.csdn.net/AntonyCheng/article/details/136555245),该模板集成了最常见的开发组件,同时基于修改配置文件实现组件的装载,除了这些,模板中还有非常丰富的整合示例,同时单体架构也非常适合SpringBoot框架入门,如果觉得有意义或者有帮助,欢迎Star & Issues & PR!

上一章:由浅到深认识Go语言(8):切片

9.切片

数组的思考

数组定义完之后,长度是固定的,一旦遇到动态变化的程序,数组使用就可能非常麻烦,所以Go语言提出了切片的概念,可以把切片理解成“动态数组”,但是他本质不是数组,在以后的编程中,切片会逐渐替代掉数组;

9.1.切片创建

//切片创建有三种方式:
//1.var 切片名 []数据类型
//2.切片名 := []数据类型
//3.使用make()函数创建:
//  3.1.make(切片类型,长度,容量)
//      切片类型就是 []数据类型
//      长度就是 初始化后真实存在的元素个数
//      容量就是 初始化最大能包含的元素个数
//      注意:容量 >= 长度
//  3.2.make(切片类型,容量)
//      这种参数列表的容量和长度相同;
package main

import "fmt"

func main() {
	var num1 []int
	fmt.Println("num1 =", num1, ",len(num1) =", len(num1), ",cap(num1) =", cap(num1))

	num2 := []int{}
	fmt.Println("num2 =", num2, ",len(num2) =", len(num2), ",cap(num2) =", cap(num2))

	num3 := make([]int, 0, 0)
	fmt.Println("num3 =", num3, ",len(num3) =", len(num3), ",cap(num3) =", cap(num3))

	num4 := make([]int, 3)
	fmt.Println("num4 =", num4, ",len(num4) =", len(num4), ",cap(num4) =", cap(num4))
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

9.2.切片初始化

package main

import "fmt"

func main() {
   var num1 []int
   fmt.Println("num1 =", num1, ",len(num1) =", len(num1), ",cap(num1) =", cap(num1))
   num1 = append(num1, 1, 2, 3, 4, 5)
   fmt.Println("num1 =", num1, ",len(num1) =", len(num1), ",cap(num1) =", cap(num1))
   num1 = append(num1, 6, 7, 8, 9, 10)
   fmt.Println("num1 =", num1, ",len(num1) =", len(num1), ",cap(num1) =", cap(num1))

   num2 := []int{1, 2, 3, 4, 5}
   fmt.Println("num2 =", num2, ",len(num2) =", len(num2), ",cap(num2) =", cap(num2))
   num2 = append(num2, 6, 7, 8, 9, 10)
   fmt.Println("num2 =", num2, ",len(num2) =", len(num2), ",cap(num2) =", cap(num2))

   num3 := make([]int, 10)
   fmt.Println("num3 =", num3, ",len(num3) =", len(num3), ",cap(num3) =", cap(num3))
   //这里循环条件是小于长度,而不是容量
   for i := 0; i < len(num3); i++ {
      num3[i] = i + 1
   }
   fmt.Println("num3 =", num3, ",len(num3) =", len(num3), ",cap(num3) =", cap(num3))
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

9.3.切片的遍历

package main

import "fmt"

func main() {
   nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
   for i := 0; i < len(nums); i++ {
      fmt.Printf("%d ", nums[i])
   }
   fmt.Println()
   for _, v := range nums {
      fmt.Printf("%d ", v)
   }
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

9.4.切片的截取

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

package main

import "fmt"

func main() {
   nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
   fmt.Println("len(nums) =", len(nums), ",cap(nums) =", cap(nums))
   fmt.Println("nums[1] =", nums[1])
   fmt.Println("nums[:] =", nums[:])
   fmt.Println("nums[5:] =", nums[5:])
   fmt.Println("nums[:5] =", nums[:5])
   fmt.Println("nums[3:7] =", nums[3:7])
   //nums[low:high:max]中 max >= high >= low
   fmt.Println("nums[3:7:5] =", nums[3:7:7])
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

问题:如果我们将切片截取后返回新切片。对新切片的值进行修改,会影响原切片么;

package main

import "fmt"

func main() {
   num1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
   num2 := []int{}
   num2 = num1[1:5]
   fmt.Println(num1)
   fmt.Println(num2)
   num2[0] = 999
   fmt.Println(num1)
   fmt.Println(num2)
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

关于切片截取的问题,在Go语言中会影响原来的切片,和Java中ArrayList相似;

9.5.append函数扩容机制

一般扩容方式是扩容至扩容前容量的2倍,如果超过1024字节,每次扩容至扩容前的1.25倍;Java中扩容机制是扩容至扩容前的1.5倍;

package main

import "fmt"

func main() {
   num := make([]int, 3, 5)
   num = append(num, 1)
   num = append(num, 2)
   fmt.Println("len(num) =", len(num))
   fmt.Println("cap(num) =", cap(num))
   num = append(num, 3)
   fmt.Println("len(num) =", len(num))
   fmt.Println("cap(num) =", cap(num))
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

9.6.copy拷贝函数

基本结构

//将切片2拷贝至切片1
copy(切片1,切片2)

示例如下:

package main

import "fmt"

func main() {
   num1 := []int{1, 2, 3, 4}
   num2 := []int{5, 6, 7, 8}
   fmt.Println("num1 =", num1)
   fmt.Println("num2 =", num2)
   copy(num1, num2)
   fmt.Println("num1 =", num1)
   fmt.Println("num2 =", num2)
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果拷贝的两个切片长度不一致,那么拷贝的长度为两个切片中长度较小的长度值;

package main

import "fmt"

func main() {
	num1 := []int{1, 2}
	num2 := []int{5, 6, 7, 8}
	fmt.Println("num1 =", num1)
	fmt.Println("num2 =", num2)
	copy(num1, num2)
	fmt.Println("num1 =", num1)
	fmt.Println("num2 =", num2)
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

9.7.切片作为函数参数

package main

import "fmt"

func main() {
   num := []int{1, 2, 3, 4}
   ints := add1(num)
   fmt.Println(ints)
}

func add1(num []int) []int {
   fmt.Println("原切片如下:")
   for _, v := range num {
      fmt.Printf("%d ", v)
   }
   fmt.Println()
   num = append(num, 1)
   fmt.Println("已经添加数字1")
   return num
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果传入后对其中的值进行了修改,原来的切片也会被一并修改,这个和数组就有区别了,和Java中的ArrayList类似;

package main

import "fmt"

func main() {
   num := []int{1, 2, 3, 4, 5}
   updateAllZero(num)
   fmt.Println("修改后的切片:")
   fmt.Println(num)
}

func updateAllZero(num []int) {
   fmt.Println("原切片如下:")
   for _, v := range num {
      fmt.Printf("%d ", v)
   }
   fmt.Println()
   for i := 0; i < len(num); i++ {
      num[i] = 0
   }
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

append() 函数本就返回了一个切片,并不是对原切片进行的操作,所以没办法改变原切片;

9.8.切片案例

案例一:

计算出一组整型数据之和;(Go与C语言类似,不能在创建数组时使用变量作为数组个数)

package main

import (
	"fmt"
)

func main() {
	num := 0
	sum := 0
	fmt.Println("请输入你要输入的数的个数:")
	fmt.Scan(&num)

	arr := make([]int, num)
	for i := 0; i < len(arr); i++ {
		fmt.Println("请输入第", i+1, "个数:")
		fmt.Scan(&arr[i])
		sum += arr[i]
	}
	fmt.Printf("sum = %d\n", sum)
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

案例二:

输出一组整型数据最大的值;

package main

import (
   "fmt"
)

func main() {
   num := 0
   fmt.Println("请输入你要比较的数的个数:")
   fmt.Scan(&num)
   arr := make([]int, num)
   for i := 0; i < len(arr); i++ {
      fmt.Println("请输入第", i+1, "个数:")
      fmt.Scan(&arr[i])
   }
   max := arr[0]
   for i := 0; i < len(arr); i++ {
      if arr[i] > max {
         max = arr[i]
      }
   }
   fmt.Println("max =", max)
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

9.9.排序

9.9.1.冒泡排序

package main

import "fmt"

func main() {
   num := []int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}
   for i := 0; i < len(num); i++ {
      for j := 0; j < i; j++ {
         if num[j] >= num[i] {
            temp := num[j]
            num[j] = num[i]
            num[i] = temp
         }
      }
      fmt.Println(num)
   }
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

9.9.2.选择排序

package main

import "fmt"

func main() {
   num := []int{38, 20, 46, 38, 74, 91, 12, 25}
   for i := 0; i < len(num); i++ {
      min := num[i]
      index := i
      for j := i; j < len(num); j++ {
         if num[j] < min {
            min = num[j]
            index = j
         }
      }
      temp := num[i]
      num[i] = min
      num[index] = temp
      fmt.Println(num)
   }
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下一章:由浅到深认识Go语言(9):map

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值