开发者

Golang中切片长度和容量的区别示例详解

目录
  • 1.切片的长度:
  • 2.切片的容量:
  • 3.通过上面两个示例看不出区别,我们看下面的示例:
  • 4.通过对切片的增加,查看切片与底层数组的变化
  • 5. 注意用法:
  • 总结

首先要知道在golang中,切片的底层实际就是数组。

1.切片的长度:

切片的长度指切片中元素的数量,可以使用len()函数查询其切片的长度。

示例1:

package main

import "fmt"

androidfunc main(){
    slice := []int{1,3,2,6,4}
    # 调用len查看长度
    length := len(slice)
    fmt.Printf("slice01的长度是:%v", length)
}

// 输出结果
// slice的长度是:5

在上面代码中,变量length就是切片的长度(结果是5)

2.切片的容量:

切片的容量是指切片底层数组的长度,可以使用cap()函数查看容量

示例2:

package maiphpn

import "fmt"

func main(){
    slice := []int{1,3,2,6,4}
    // 调用cap查看容量
    capacity := cap(slice)
    fmt.Printf("slice01的容量是:%v", capacity)
}

// 输出结果
// slice的容量是:5

在上面代码中,变量capacity就是切片的容量(结果也是5)

3.通过上面两个示例看不出区别,我们看下面的示例:

示例3

package main

import "fmt"

func main(){
    // 通过make函数来创建slice, 4表示切片的长度, 10标识切片的容量
    slice := make([]int, 4, 6)
    length := len(slice)
    capacity := cap(slice)
    fmt.Printf("slice01的长度是:%v\n", length)
    fmt.Printf("slice01的容量是:%v\n", capacity)
}

//编程 输出结果
// slice01的长度是:4
// slice01的容量是:6

你可以想象成:当执行slice := make([]int, 4, 10)的时候,程序在底层创建了一个长度为6的数组,切片slice引用了前面4个元素,就生成了slice这个切片,当前切片值是:{0, 0, 0, 0},剩下的2个元素则暂时没有引用。

4.通过对切片的增加,查看切片与底层数组的变化

我们知道,golang中切片和数组的主要区别在于数组是定长的,切片是变长的。但我们在示例3中定义了切片的容量是6,那如果超过6个元素了,将会发生什么呢?

示例4

package main

import "fmt"

func main(){
    // 通过make函数来创建slice, 4表示切片的长度, 10标识切片的容量
    slice := make([]int, 4, 6)
    length := len(slice)
    capacity := cap(slice)
    fmt.Printf("slice01的长度是:%v\n", length)
    fmt.Printf("slice01的容量是:%v\n", capacity)
    
    //第一次向切片slice内添加元素
 编程客栈   slice = append(slice, 1)
    //打印slice的长度,容量,内存地址(slice[0]的内存地址)
    fmt.Printf("\n\n第一次结果:")
    fmt.Printf("slice的长度是:%v\n", len(slice))
    fmt.Printf("slice的容量是:%v\n", cap(slice))
    fmt.Printf("slice的内存地址是:%v\n", &slice[0])
    
    // 第二次向slice内添加元素
    slice = append(slice, 1)
    //打印slice的长度,容量,内存地址(slice[0]的内存地址)
    fmt.Printf("\n\n第二次结果:")
    fmt.Printf("slice的长度是:%v\n", len(slice))
    fmt.Printf("slice的容量是:%v\n", cap(slice))
    fmt.Printf("slice的内存地址是:%v\n", &slice[0])
    
    // 第三次向slice内添加元素
    slice = append(slice, 1)
    //打印slice的长度,容量,内存地址(slice[0]的内存地址)
    fmt.Printf("\n\n第三次结果:")
    fmt.Printf("slice的长度是:%v\n", len(slice))
    fmt.Printf("slice的容量是:%v\n", cap(slice))
    fmt.Printf("slice的内存地址是:%v\n", &slice[0])
}

// slice01的长度是:4
// slice01的容量是:6


// 第一次结果:slice的长度是:5
// slice的容量是:6
// slice的内存地址是:0xc00000e390


// 第二次结果:slice的长度是:6
// slice的容量是:6
// slice的内存地址是:0xc00000e390


// 第三次结果:slice的长度是:7
// slice的容量是:12
// slice的内存地址是:0xc000060060

通过示例4我们可以发现:我们初始化切片长度为4, 容量为6的时候。

当第一次和第二次向切片内添加元素后,只有切片的长度增加,容量和内存地址都没改变

当第三次向切片内添加元素后,长度增加了1,容量变成了之前的2倍,内存地址也发生了改变。

由此我们可以推断出:

**总结:**当切片的元素长度超过了默认编程客栈的容量之后,程序会重新创建一个底层数组和切片绑定,且新的数组的长度为原来的两倍(切片的容量变成原来的两倍)

5. 注意用法:

示例5

package main

import "fmt"

func main() {
	slice := make([]int, 4, 4)
	slice2 := make([]int, 4, 5)
    // 调用下方定义的test函数
	test(slice)
	test(slice2)

	// 输出两个切片调用test函数后的结果
	fmt.Printf("slice的结果: %v\n", slice)
	fmt.Printf("slice2的结果: %v\n", slice2)

}

func test(s []int) {
	s = append(s, 1)
	for i := 0; i < len(s); i++ {
		s[i] = 100
	}
}

// slice的结果: [0 0 0 0]
// slice2的结果: [100 100 100 100]

切片容量不同,导致了最终结果不同。

总结

到此这篇关于Golang中切片长度和容量区别的文章就介绍到这了,更多相关Golang切片长度和容量内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新开发

开发排行榜