深入理解golang — 数组(array)、切片(slice)、map

我比较喜欢先给出代码,然后得出结论

数组

 1 package main
 2
 3 import (
 4     "fmt"
 5 )
 6
 7 func main() {
 8     arr := [...]int{1, 2, 3}
 9     //打印初始的指针
10     fmt.Printf("the pointer is : %p \n", &arr)
11     printPointer(arr)
12 }
13
14 func printPointer(any interface{}) {
15     fmt.Printf("the pointer is : %p \n", &any)
16 }

结果

1 the pointer is : 0xc082008580
2 the pointer is : 0xc0820001d0 

切片

 1 package main
 2
 3 import (
 4     "fmt"
 5 )
 6
 7 func main() {
 8     arr := make([]int, 3)
 9     //打印初始的指针
10     fmt.Printf("the pointer is : %p \n", arr)
11     printPointer(arr)
12 }
13
14 func printPointer(any interface{}) {
15     fmt.Printf("the pointer is : %p \n", any)
16 }

结果

1 the pointer is : 0xc082008580
2 the pointer is : 0xc082008580 

map

 1 package main
 2
 3 import (
 4     "fmt"
 5 )
 6
 7 func main() {
 8     arr := make(map[int]string)
 9     //arr := [3]int{1, 2, 3}
10     //打印初始的指针
11     fmt.Printf("the pointer is : %p \n", arr)
12     printPointer(arr)
13 }
14
15 func printPointer(any interface{}) {
16     fmt.Printf("the pointer is : %p \n", any)
17 }

运行结果

1 the pointer is : 0xc082007c80
2 the pointer is : 0xc082007c80 

由此,我们看到数组本身传过去的是值,传到函数之后,被开辟了另外一个空间。

因为数组就是他本身。这一句好像不太好理解。

这是切片 arr := make([]int, 3)  而arr 本身不是一个数组,至少不是我们所想要的指向的一个数组。只是arr里有一个地址指向数组。

这么举个例子:

arr := [...]int{1,2,3,4,5} 这是一个数组,懂得go语言的都明白。  arr本身就是数组

arrSlice := arr[0:5]  这是一个切片。 打印所得的值是一样的,和上面。  arrSlice本身不是数组,只是arrSlice本身有一个值是指向arr的指针。

切片是指一个结构体,大体结构像这样

1 struct slice{
2     ptr *Elem
3     len int
4     cap int
5 }

也就是说,上面的arrSlice其实是一个结构体。里面有一个属性 ptr指向数组 arr

其实arrSlice也是传到函数里,也是进行了复制。但是尽管传过去是一个复制的结构体,他的属性ptr,没有变。还是一个指向原数组的指针。

下面的例子见证他自己传过去,是一个复制的过程:

 1 package main
 2
 3 import (
 4     "fmt"
 5 )
 6
 7 func main() {
 8     arrSlice := make([]int, 4)
 9     fmt.Printf("the pointer is : %p \n", arrSlice)
10     fmt.Printf("the pointer is : %p \n", &arrSlice) //这是arrSlice本身的指针,也就是结构体的指针
11     printPointer(arrSlice)
12 }
13
14 func printPointer(any interface{}) {
15     fmt.Printf("the pointer is : %p \n", any)
16     fmt.Printf("the pointer is : %p \n", &any) //打印传过来的结构体arrSlice的指针
17 }

看结果:

1 the pointer is : 0xc0820085a0
2 the pointer is : 0xc082008580
3 the pointer is : 0xc0820085a0
4 the pointer is : 0xc0820001d0 

第1、3个的打印是打印这个结构体的ptr属性,也就是指向数组的指针。

其实这个结构体传到函数里,是一个复制的过程,第2、4的指针不一样。

大家在对照下面的图片理解一下:

时间: 2024-11-06 09:32:46

深入理解golang — 数组(array)、切片(slice)、map的相关文章

伪数组转为数组 Array.prototype.slice.call(arguments)

我们知道,Array.prototype.slice.call(arguments)能将具有length属性的对象转成数组,除了IE下的节点集合(因为ie下的dom对象是以com对象的形式实现的,js对象与com对象不能进行转换) 1 var a={length:2,0:'first',1:'second'}; 2 Array.prototype.slice.call(a);// ["first", "second"] 3 4 var a={length:2}; 5

转对象(含length属性)成数组Array.prototype.slice.call(arguments)

我们知道,Array.prototype.slice.call(arguments)能将具有length属性的对象转成数组,除了IE下的节点集合(因为ie下的dom对象是以com对象的形式实现的,js对象与com对象不能进行转换) 如: 1 var a={length:2,0:'first',1:'second'}; 2 Array.prototype.slice.call(a);// ["first", "second"] 3 4 var a={length:2}

golang中Array与Slice

在golang中有数组和Slice两种数据结构,Slice是基于数组的实现,是长度动态不固定的数据结构,本质上是一个对数组字序列的引用,提供了对数组的轻量级访问.那么在go的函数中以数组或Slice为形参的时候就存在一些差别. ? 首先,golang中是值传递,并且如果传递的参数是数组的时候并不会隐式将数组作为引用或者指针传入,而是传入副本,而如果想轻量级传递数据,这个时候就需要使用slice了. 可以通过一个简单的例子来验证这个机制: package main import "fmt"

元组Tuple、数组Array、映射Map

一.元组Tuple 元组Tuple是不同类型的值的聚集,元组的值将单个的值包含在圆括号中来构成,元组可以包含一个不同类型的元素 如 val riple = (100, "Scala" , "Spark")1.元组中可以包含不同类型的元素,如上,把鼠标放在riple上,IDE会自动推断出元组riple里面的3个元素类型分别是Int.String.String2.元组实例化后,和数组Array不同,数组Array的索引从0开始,而元组Tuple的索引从1开始.3.调用元

类数组转数组Array.prototype.slice.call(arrayLike)

转换方式:Array.prototype.slice.call(arrayLike) 附:(http://www.jianshu.com/p/f8466e83cef0) 首先Array.prototype.slice.call(arrayLike)的结果是将arrayLike对象转换成一个Array对象.所以其后面可以直接调用数组具有的方法.譬如 Array.prototype.slice.call(arrayLike).forEach(function(element,index){  //可

golang数组与切片

golang中坑的慢慢踩! 我们都知道golang中的切片是引用类型,但是在函数中使用append给切片追加元素是行不通的,需要使用切片的指针类型才能增加元素 数组的使用: package main import ( "fmt" ) func ChangeArr(arr [5]int) { arr[0] = 6 } func ChangeArr2(arr *[5]int) { arr[0] = 6 } func main() { a := [5]int{1, 2, 3, 4, 5} P

GO语言数组,切片,MAP总结

数组 数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整形.字符串或者自定义类型. 数组的长度必须是常量,并且长度是数组类型的一部分.一旦定义,长度不能变.数组可以通过下标进行访问,下标是从0开始,最后一个元素下标是:len-1,访问越界(下标在合法范围之外),则触发访问越界,会panic. 数组是值类型,赋值和传参会复制整个数组.因此改变副本的值,不会改变本身的值. 数组声明 var 数组变量名 [元素数量]元素类型 var a [3]int //声明

JS的数组进行切片slice

代码 var arr = new Array(6) arr[0] = "George" arr[1] = "John" arr[2] = "Thomas" arr[3] = "James" arr[4] = "Adrew" arr.slice(0,3) 和pyhon一样,左包含,又不包含,字符串也支持,因为字符串是特殊的数组 原文地址:https://www.cnblogs.com/robinunix/p/

GO語言基礎教程:array,slice,map

這節課我們來講解數組,切片和map,或許您是從其他語言轉到GO語言這邊的,那麼在其他語言的影響下您可能會不太適應GO語言的數組,因為GO語言把數組給拆分成了array,slice和map,接下來的時間讓我們一起研究一下這三者的差異以及用法.首先我們說一下array的部份: 1.數組的長度屬於數組的一部份,我們看下邊的例子 a:=[1]int{}和b:=[2]int{} a和b都是數組,但是他們的長度不同,在GO語言中會認為是不同的兩種類型,既然是不同的類型,那麼他們就不能進行比較或直接賦值的操作