惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

爱范儿
爱范儿
量子位
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
J
Java Code Geeks
B
Blog
V
V2EX
博客园 - 三生石上(FineUI控件)
Blog — PlanetScale
Blog — PlanetScale
aimingoo的专栏
aimingoo的专栏
Y
Y Combinator Blog
F
Fortinet All Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
A
About on SuperTechFans
D
DataBreaches.Net
阮一峰的网络日志
阮一峰的网络日志
博客园 - Franky
H
Help Net Security
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
酷 壳 – CoolShell
酷 壳 – CoolShell
MongoDB | Blog
MongoDB | Blog
L
LangChain Blog

博客园 - 夏之夜

Linux 学习笔记之(十四)二进制分析工具 GO 学习笔记之四 工具(1)远程调试工具 dlv Shell命令集锦(一) Postgres 数据库(三)常见DDL命令 elasticsearch 学习笔记之五 备份还原开源方案比较 elasticsearch 学习笔记之四 快照 GO 学习笔记之一 环境安装 GO 学习笔记之零 (四)字符串处理集锦 GO 学习笔记之零 (三)常见问题处理集锦 GO 学习笔记之三 基础语法(12)文件操作 GO 学习笔记之五 编程(三)单元测试 ( VSCODE工具运行 ) GO 学习笔记之三 基础语法(11) 数据类型转换 GO 学习笔记之零 (二)git 操作(VSCODE) GO 学习笔记之零 (一)GO推荐的工程目录结构 Git 学习笔记之(六)windows 上 git 工具 安装 GO 学习笔记之二 常用命令集锦 elasticsearch 学习笔记之一 elasticdump elasticsearch 学习笔记之二 常见接口 专题(二十) cut
GO 学习笔记之三 基础语法(5) 切片
夏之夜 · 2024-12-27 · via 博客园 - 夏之夜

一、定义

Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

其存在容量和长度的说法,长度是实际数据的长度,容量是可容纳的数组长度。容量也可以进行扩充或缩减。

1、初始化时直接赋值

//1.直接初始化切片,[] 表示是切片类型,{1,2,3} 初始化值依次是 1,2,3,其 cap=len=3。
s := []int{1, 2, 3}

2、从已有的动态数组中初始化

//初始化切片 s1,是数组 s 的引用。  将数组s的值全部给s1,s\s1 数组内容一样
s1 := s[:]
//初始化切片 s2,是从下标 startIndex 到 endIndex-1 下的元素创建为一个新的切片。
s2 := s[1:3]

3、初始化时不赋值,使用默认值

//使用make初始化切片 make(数组变量,长度,容量)
s3 := make([]int, 3)   #定义了长度为3的数组
s4 := make([]int, 3,5)  #定义了长度为3,容量为5 的数组,有长度的下标0,1,2 才有初始值 0, 剩下两个容量无

4、定义空数组(空切片)

     仅进行了声明,但是长度和容量都未定义,且未进行数组的赋值

package main
 
import "fmt"
 
func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
 
func main() {
 
//3.空切片
var numbers []int
printSlice(numbers)
if numbers == nil {
fmt.Println("切片是空的呢")
}
}

完整如下:

package main
 
import "fmt"
 
func main() {
//1.直接初始化切片,[] 表示是切片类型,{1,2,3} 初始化值依次是 1,2,3,其 cap=len=3。
s := []int{1, 2, 3}
fmt.Println("切片s:", s)
//初始化切片 s1,是数组 s 的引用。
s1 := s[:]
fmt.Println("切片s1:", s1)
//初始化切片 s2,是从下标 startIndex 到 endIndex-1 下的元素创建为一个新的切片。
s2 := s[1:3]
fmt.Println("切片s2:", s2)
//使用make初始化切片
s3 := make([]int, 3)
fmt.Println("切片s3:", s3)
}

二、使用

1、从已有的动态数组中截取出子数组

  数组名2 := 数组名1[startIndex:endIndex]       #表示从数组中截取下表为startIndex的项一直到endIndex-1的项

//初始化切片 s2,是从下标 startIndex 到 endIndex-1 下的元素创建为一个新的切片。
s2 := s[1:3]
package main
 
import "fmt"
 
func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
 
func main() {
 
//切片截取举例
/* 创建切片 */
numbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8}
printSlice(numbers)
 
/* 打印原始切片 */
fmt.Println("numbers ==", numbers)
 
/* 打印子切片从索引1(包含) 到索引4(不包含)*/
fmt.Println("numbers[1:4] ==", numbers[1:4])
 
/* 默认下限为 0*/
fmt.Println("numbers[:3] ==", numbers[:3])
 
/* 默认上限为 len(s)*/
fmt.Println("numbers[4:] ==", numbers[4:])
 
numbers1 := make([]int, 0, 5)
printSlice(numbers1)
 
/* 打印子切片从索引 0(包含) 到索引 2(不包含) */
number2 := numbers[:2]
printSlice(number2)
 
/* 打印子切片从索引 2(包含) 到索引 5(不包含) */
number3 := numbers[2:5]
printSlice(number3)
}

2、计算数组的长度和容量

  • len() 方法获取切片的长度
  • cap()方法 可以测量切片最长可以达到多少
package main
 
import "fmt"
 
func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
 
func main() {
 
//2调用printSlice方法获取切片的长度与容量
var numbers = make([]int, 3, 5)
printSlice(numbers)
}

3、扩容

如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来。

  • append()     #当长度和容量相同时,通过append 方式增加元素,长度和容量都会增加
  • copy() 
package main
 
import "fmt"
 
func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
 
func main() {
 
//5.append() 和 copy() 函数
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)
}

 4、将字符串根据分隔符转成切片

   strings.Split(字符串,分割符)

func auth() gin.HandlerFunc {
    _token_ignored_urls := service.GetStringFromInneral("token.ignored")   // 从properties文件中读取 token.ignored 配置项的值
    _token_ignored_urls = strings.TrimSpace(_token_ignored_urls)   //去掉空格
    if len(_token_ignored_urls) != 0 {   
        return authWhitelist(strings.Split(_token_ignored_urls, ","))   将字符串 _token_ignored_urls 按照 逗号 进行分割形成 切片
} return authWhitelist(nil) }

 5、遍历切片

 for .... range  

5.1 遍历切片所有值(不修改)

amounts:=[]float64{237.81,261.87,273.93,279.99}
sum:=0.0
for _,amount:=range amounts{
   sum+=amount
}

 for _,amount:=range amounts 说明

  • _ 是切片的索引,本示例中由于不需要用索引,所以直接通过_进行了丢弃
  • amount 是 amounts 对应索引上的值的副本

5.2 遍历切换指定起止之间的子切片

for _,amount:=range amounts[:5]{
   sum+=amount
}

 表示遍历前5个元素

5.3 修改切片元素内容(直接使用索引)

for i:=range amounts{
   amounts[i]+=1.5
   sum+=amount[i]
}