golang基础-数组、切片创建_内存_底层实现_修改值_拷贝_循环、string与切片
来源:互联网 发布:淘宝禁止开店 编辑:程序博客网 时间:2024/06/05 05:17
数组
数组:是同一种数据类型的固定长度的序列
数组定义:var a [len]int,比如:var a[5]int,一旦定义,长度不能变
长度是数组类型的一部分,因此,var a[5] int和var a[10]int是不同的类型
数组可以通过下标进行访问,下标是从0开始,最后一个元素下标是:len-1
访问越界,如果下标在数组合法范围之外,则触发访问越界,会panic
数组是值类型,因此改变副本的值,不会改变本身的值
package mainimport( "fmt")func main() { //为数组索引赋值 var a [5]int a[0] = 10 fmt.Println(a) //遍历数组2种方法 for i:=0;i<len(a);i++{ fmt.Println(a[i]) } for i,v := range a{ fmt.Println(i,v) } //值传递 test() var aa [5]int //通过方法参数值传递 test1(aa) fmt.Println(aa) //传递地址值 test2(&aa) fmt.Println(aa) //数组初始化5种方式 var arr1 [5]int = [5]int{1,2,3,4,5} fmt.Println(arr1) var arr2 = [5]int{1,2,3,4,5} fmt.Println(arr2) var arr3 = [...]int{1,2,4,5,6} fmt.Println(arr3) var arr4 = [...]int{1:1,2:2} fmt.Println(arr4) var arr5 = [5]int{1:2,3:4} fmt.Println(arr5)}func test(){ var a [5]int b := a b[0] = 100 fmt.Println(a)}func test1(arr [5]int){ arr[0] = 100}func test2(arr *[5]int){ (*arr)[0] = 100}
输出如下:
[10 0 0 0 0]1000000 101 02 03 04 0[0 0 0 0 0][0 0 0 0 0][100 0 0 0 0][1 2 3 4 5][1 2 3 4 5][1 2 4 5 6][0 1 2][0 2 0 4 0]
切片
切片:切片是数组的一个引用,因此切片是引用类型
切片的长度可以改变,因此,切片是一个可变的数组
切片遍历方式和数组一样,可以用len()求长度
cap可以求出slice最大的容量,0 <= len(slice) <= (array),其中array是slice引用的数组
切片的定义:var 变量名 []类型,比如 var str []string var arr []int
package mainimport( "fmt")func main() { var slice []int var arr [5]int = [5]int{1,2,3,4,5} slice = arr[2:5] fmt.Println(slice) //长度 fmt.Println(len(slice)) //最大容量 fmt.Println(cap(slice)) slice = slice[0:1] fmt.Println(len(slice)) fmt.Println(cap(slice)) //切片的其他声明方法 var slice1 []int = arr[:] fmt.Println(slice1) var slice2 []int = arr[0:3] fmt.Println(slice2) var slice3 []int = []int{1,2,4} fmt.Println(slice3)}
输出如下:
2017/10/24 13:46:43 debugger.go:499: continuing[3 4 5]3313[1 2 3 4 5][1 2 3][1 2 4]
切片内存如何变化的?
package mainimport( "fmt")func main() { var a [5]int = [...]int{1,2,3,4,5} //切片 s:= a[1:] s[1] = 100 //内存地址一样,修改了s的索引值,也就修改了a的索引值 fmt.Printf("%p %p\n",s,&a[1]) fmt.Println("before a:",a) fmt.Println(s) s = append(s,10) s = append(s,10) s = append(s,10) s = append(s,10) s = append(s,10) s[1] = 1000 fmt.Println("after a:",a) fmt.Println(s) //容量改变,重新分配内存 fmt.Printf("%p %p\n",s,&a[1])}
输出如下:
0xc04204c1e8 0xc04204c1e8before a: [1 2 100 4 5][2 100 4 5]after a: [1 2 100 4 5][2 1000 4 5 10 10 10 10 10]0xc042014200 0xc04204c1e8PS E:\golang\go_pro\src\safly>
简单解释下:
创建一个数组a,初始值为{1,2,3,4,5},然后构造一个从索引1开始的数组切片,{2,3,4,5},这里的切片、数组都是同一块内存地址,然后将s[1]赋值为100,由于内存地址是一样的,所以a为{1,2,100,4,5}
s为[2,100,4,5]
接下来为s切片扩充容量,然后修改了s[1] = 1000,最后s为2 1000 4 5 10 10 10 10 10,a依然是[1 2 100 4 5]
,由于底层算法,扩容后,内存地址a和s的就不同了,s从新创建了一个内存地址0xc042014200
切片的底层代码实现
package mainimport( "fmt")/*切片底层形式*/type slice struct{ ptr *[5]int len int cap int}/*构造一个slice*/func makeSlice(s slice,cap int) slice{ s.ptr = new([5]int) s.cap = cap s.len = 0 return s}func testSlice(){ //slice类型 var a slice a = makeSlice(a,5) a.ptr[0] = 100 fmt.Println(a.ptr)}func main() { testSlice()}
输出如下:
&[100 0 0 0 0]
修改切片值、演示切片内存地址
package mainimport( "fmt")/*切片会被修改*/func modify(b []int){ b[1] = 200}func modify1(b *[]int){ (*b)[1] = 2000}func main() { var b []int = []int{1,2,3} fmt.Println(b) //修改切片方法1--直接穿切片 modify(b) fmt.Println(b) //修改切片方法2--传地址值 modify1(&b) fmt.Println(b) //数组不会被修改,参数为数组 var d [3]int = [...]int{3,4,5} modify3(d) fmt.Println(d)/*演示切片的内存布局*/ testSlice5()}func modify3(b [3]int){ b[1] = 200}/*演示切片的内存布局*/func testSlice5(){ fmt.Println("----------------") var a = [10]int{1,2,3,4} b :=a[1:5] fmt.Printf("%p\n",b) fmt.Printf("%p\n",&a[1]) fmt.Println(a,b)}
输出如下:
[1 2 3][1 200 3][1 2000 3][3 4 5]----------------0xc0420101e80xc0420101e8[1 2 3 4 0 0 0 0 0 0] [2 3 4 0]PS E:\golang\go_pro\src\safly>
切片拷贝make\copy\append
package mainimport( "fmt")func main() { var a []int= []int{1,2,3,4,5,6} fmt.Println(a) b:= make([]int,1) fmt.Println(b) //将a的值拷贝到b copy(b,a) fmt.Println(b) //将a拷贝到c c:=make([]int,10) copy(c,a) fmt.Println(c) //append自己 d :=append(c,c...) fmt.Println(d) //append元素 e:=append(c,2,4) fmt.Println(e)}
输出如下:
PS E:\golang\go_pro\src\safly> go run demo.go[1 2 3 4 5 6][0][1][1 2 3 4 5 6 0 0 0 0][1 2 3 4 5 6 0 0 0 0 1 2 3 4 5 6 0 0 0 0][1 2 3 4 5 6 0 0 0 0 2 4]PS E:\golang\go_pro\src\safly>
string与slice
string底层就是一个byte的数组,因此,也可以进行切片操作
string本身是不可变的,因此要改变string中字符,需要如下操作
package mainimport( "fmt")func main() { s:="hellogo" s1:=s[0:3] s2:=s[2:] fmt.Println(s1) fmt.Println(s2) testModifyStr()}func testModifyStr(){ //带中文的 s:="我的hellogo" s1:=[]rune(s) s1[1] = 'a' str:=string(s1) fmt.Println(str) aaa := "hello world" bbb := []byte(aaa) bbb[0] = 'o' str = string(bbb) fmt.Println(str)}
输出如下:
helllogo我ahellogooello worldPS E:\golang\go_pro\src\safly>
切片循环
package mainimport( "fmt")func main() { var a []int= []int{1,2,3,4,5,6} fmt.Println(a) for index, val := range a { fmt.Println(index,val) } for _, val := range a { fmt.Print`n(val) }}
输出如下:
PS E:\golang\go_pro\src\safly> go run demo.go[1 2 3 4 5 6]0 11 22 33 44 55 6123456PS E:\golang\go_pro\src\safly>
- golang基础-数组、切片创建_内存_底层实现_修改值_拷贝_循环、string与切片
- mongodb_分布式存储_切片
- 62_数组的拷贝_排序_二分法_命令行参数_增强for循环
- 数组_拷贝与排序
- python基础四_函数,切片,迭代
- DayDayUP_Python自学记录[9]_切片
- python_pandas_dataframe_行列选择_切片操作
- ^_^
- ^_^
- ^_^
- ^_^
- *_&
- ...!@~....!@#....+_#%.
- ^_^
- ^_^
- ^_^
- ^_^
- *_*
- Apache的DBUtils使用详解
- leetcode 88. Merge Sorted Array
- leetcode
- Android Studio自带图标库和开源图标库怎么使用?
- printf
- golang基础-数组、切片创建_内存_底层实现_修改值_拷贝_循环、string与切片
- LeetCode 1. Two Sum
- mysqldump,数据备份与恢复
- 使用BigInteger来处理权限问题,
- 归并排序
- 自定义popWindow布局
- Map的使用
- STM32 模拟 I2C
- depth estimation 深度估计