转载自:http://studygolang.com/articles/724 1. slice1:= slice[0:2] 引用,非复制,所以任何对slice1或slice的修改都会影响对方 data := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0} data1 := data[0:2] data1[0] = 99 fmt.Println(data1) fmt.Println(data) [99 2] [99 2 3 4 5 6 7 8 9 0] 2.append…
数组 Go的切片是在数组之上的抽象数据类型,因此在了解切片之前必须要要理解数组.数组类型由指定和长度和元素类型定义.数组不需要显式的初始化:数组元素会自动初始化为零值:Go的数组是值语义.一个数组变量表示整个数组,它不是指向第一个元素的指针(比如C语言的数组).当一个数组变量被赋值或者被传递的时候,实际上会复制整个数组.(为了避免复制数组,你可以传递一个指向数组的指针,但是数组指针并不是数组.)可以将数组看作一个特殊的struct,结构的字段名对应数组的索引,同时成员的数目固定. 切片 数组虽然…
本文从源码角度学习 golang slice 的创建.扩容,深拷贝的实现. 内部数据结构 slice 仅有三个字段,其中array 是保存数据的部分,len 字段为长度,cap 为容量. type slice struct { array unsafe.Pointer // 数据部分 len int // 长度 cap int // 容量 } 通过下面代码可以输出空slice 的大小: package main import "fmt" import "unsafe"…
1.先做个小实验 func main(){ s1:=make([]int,0,10) s1=[]int{1,2,3} ss:=make([]int,0,10) ss = s1[1:] for i:=0;i<len(ss);i++{ ss[i] +=10 } fmt.Println(s1) // [1 12 13] ss =append(ss,4) for i:=0;i<len(ss);i++{ ss[i] +=10 } fmt.Println(s1) // [1 12 13] 而不是 [1,2…
golang 中的 slice 非常强大,让数组操作非常方便高效.在开发中不定长度表示的数组全部都是 slice .但是很多同学对 slice 的模糊认识,造成认为golang中的数组是引用类型,结果就是在实际开发中碰到很多坑,以至于出现一些莫名奇妙的问题,数组中的数据丢失了. 下面我们就开始详细理解下 slice ,理解后会对开发出高效的程序非常有帮助. 这个是 slice 的数据结构,它很简单,一个指向真实 array 地址的指针 ptr ,slice 的长度 len 和容量 cap . 其…
关于获取slice相关内存地址操作 s := make([]int, 1) t.Log(unsafe.Pointer(&s))// 获取当前slice 结构体实例的内存地址 t.Log(unsafe.Pointer(&(s[0]))) // 获取底层数组第一个元素的内存地址 t.Logf("%p\n", s)// 获取底层数组的内存地址,对于数组而言,数组是一个连续的内存空间,实际数组的内存地址就是数组内第一个元素的内存地址 对于切片执行append操作每次都会生成新的…
1. array   同一类型数据的集合     var arr [n]type    //声明type类型一维数组     var arr [m][n]type //声明type类型二维数组     多维数组以此类推     也可以用 := 声明     arr := [n]type{元素1[,元素2, ...]} 其中n可以用 "..." 三个点表示,系统会根据元素个数来确定   下标只能为 int 类型,而 php 还支持 string 类型的下标   1.1 数组长度 len(…
golang 在for range一个slice时,会读出其cap长度.在for的过程中,即使动态append该slice,最终for也会在第一次读取的cap长度处停止. package main import ( "fmt" ) func main() { s := make([]) s[]="a" s[]="b" s[]="c" for _,i := range s { s = append(s, s[]) fmt.Pri…
golang中slice(切片)是常用的类型, slice是对数组进行封装 package main import ( "fmt" "strconv") func testLenCap() { strs := make([]string, 5, 10) //可以只有一个数字参数, 那么cap=len, make([]string, 5, 5) 等价于 make([]string, 5) fmt.Printf("value=%v, is nil=%v\n&q…
1.slice因capacity不足而重新分配的underlying array与原本的array空间是断裂的,就是说这是原本指向的空间没变,如下 arr := [...]int{1, 2, 3, 4, 5, 6} aslice := make([]int, 2, 3) aslice = append(aslice, 11, 12) aslice[0] = 10 fmt.Println(arr[0],aslice[0])//10 10…
slice陷阱,slice底层指向某个array,在赋值后容易导致array长期被引用而无法释放…
原文链接 : http://www.bugclosed.com/post/16 背景 go语言中切片slice是方便且好用的强大数据结构,但是使用的时候需要注意,不然容易出问题,最近因为遇到了一个slice的使用问题,比较典型. 有一个功能需求,用户需要获取1-20的不重复随机序列. 逻辑实现 由于是需要固定的1-20共20个不同数字,所以直接定义好了唯一序列如下: var( originalNumbers = []uint32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11…
一 · 比较slice 与 list 遍历创建和添加元素速度. package main import ( "time" "fmt" "container/list" ) func main() { t := time.Now() sli:=make([]int ,10) for i := 0; i<1*100000*1000;i++ { sli=append(sli, 1) } fmt.Println("slice 创建速度:&…
package mainimport "fmt"func main() { testAppend() testCopy() testDelete()}func testAppend() { var sl = make([]int,2) sl[0] = 1 sl[1] = 2 fmt.Println(len(sl)) fmt.Println(cap(sl)) sl = append(sl, 3) //sl = append(sl, 4) fmt.Println(sl) fmt.Print…
slice底层其实是一个结构体,len.cap.array分别表示长度.容量.底层数组的地址,当slice作为函数的参数传递的时候,跟普通结构体的传递是没有区别的:如果直接传slice,实参slice是不会被函数中的操作改变的,但是如果传递的是slice的指针,是会改变原来的slice的:另外,无论是传递slice还是slice的指针,如果改变了slice的底层数组,那么都是会影响slice的,这种通过数组下标的方式更新slice数据,是会对底层数组进行改变的,所以就会影响slice. 如 pa…
  arr := [...],,,,,,,,} s1 :=arr[:] s2 :=arr[:] s1=? //2,3,4,5 s2=? // 5,6 package main import "fmt" func main() { arr := [], , , , , , , } s1 := arr[:] s2 := s1[:] fmt.Println(s1) fmt.Printf("%v",s2) fmt.Println(arr) s3 :=append(s2,)…
1 前言 仅供记录使用. 2 代码 /** * @Author: FB * @Description: * @File: SliceMapInit.go * @Version: 1.0.0 * @Date: 2019/7/5 14:39 */ package main import "fmt" func main(){ InitSlice() InitMap() } func InitSlice(){ //三个等价 var a []int var a1 = []int{} var b…
原文链接:https://www.jianshu.com/p/603be4962a62 demo package main import ( "fmt" "sort" ) /*slice 简单排序示例*/ func main() { //定义一个年龄列表 ageList := []int{, , , , , , } //排序,实现比较方法即可 sort.Slice(ageList, func(i, j int) bool { return ageList[i] &l…
1) 基础语言描述理解考察https://www.tutorialspoint.com/go/go_interview_questions.htm这里有一栏.全面的问答,并且非常基础也包括golang的一些开放性话题的讨论 基础语言代码考察http://www.golangpro.com/2015/08/golang-interview-questions-answers.html 10个基本问题考察https://www.toptal.com/go/interview-questions (2…
1.直接声明:var slice []int 2.new: slice := *new([]int) 3.字面量:slice := []int{1,2,3,4,5} 4.make: slice :=  make([]int, 5, 10) 5.从切片或数组“截取”:slice := array[1:5] 或 slice := sourceSlice[1:5] Golang Slice,以及append函数的陷阱: slice并不是单纯的一个指向数组的指针,它是一个结构体(包含:指针,长度,容量)…
切片(slice)是 Golang 中一种比较特殊的数据结构,这种数据结构更便于使用和管理数据集合.切片是围绕动态数组的概念构建的,可以按需自动增长和缩小.切片的动态增长是通过内置函数 append() 来实现的,这个函数可以快速且高效地增长切片,也可以通过对切片再次切割,缩小一个切片的大小.因为切片的底层也是在连续的内存块中分配的,所以切片还能获得索引.迭代以及为垃圾回收优化的好处.本文将介绍 Golang 切片的基本概念和用法,演示环境为 ubuntu 18.04 & go1.10.1. 切…
https://www.jianshu.com/p/354fce23b4f0 切片(slice)是 Golang 中一种比较特殊的数据结构,这种数据结构更便于使用和管理数据集合.切片是围绕动态数组的概念构建的,可以按需自动增长和缩小.切片的动态增长是通过内置函数 append() 来实现的,这个函数可以快速且高效地增长切片,也可以通过对切片再次切割,缩小一个切片的大小.因为切片的底层也是在连续的内存块中分配的,所以切片还能获得索引.迭代以及为垃圾回收优化的好处. 本文将介绍 Golang 切片的…
传值还是传引用 调用函数时, 传入的参数的 传值 还是 传引用, 几乎是每种编程语言都会关注的问题. 最近在使用 golang 的时候, 由于 传值 和 传引用 的方式没有弄清楚, 导致了 BUG. 经过深入的尝试, 终于弄明白了 golang 的 传值 的 传引用, 尝试过程记录如下, 供大家参考! golang 本质上都是传值方式调用 严格来说, golang 中都是传值调用, 下面通过例子一一说明 普通类型的参数 这里的普通类型, 指的是 int, string 等原始的数据类型, 这些类…
1) Append a slice b to an existing slice a: a = append(a, b...) 2) Copy a slice a to a new slice b: b = make([]T, len(a)) copy(b, a) 3) Delete item at index i: a = append(a[:i], a[i+1:]...) 4) Cut from index i till j out of slice a: a = append(a[:i],…
slice的增删改查: //删除 func remove(slice []interface{}, i int) []interface{} { // copy(slice[i:], slice[i+1:]) // return slice[:len(slice)-1] :]...) } //新增 func add(slice []interface{}, value interface{}) []interface{} { return append(slice, value) } //插入…
相同点 由相同类型的元素组合构成 元素有序排列,0为第一个元素下标 基本使用方法相同 区别 array声明时需要指定容量大小,而且无法修改 slice可通过append增加元素,当容量不够时,会自动扩容 array传递类型:值拷贝:slice传递类型:引用拷贝(有两种情况坑) 声明 var array名 [容量]元素类型 array名 :=[3]元素类型{元素1,元素2,元素3} var slice名 []元素类型 slice名 := make([]类型,容量) //建议这样声明 slice名…
package main import "fmt" func main(){ ]int slice:=array[:] slice[]='a' slice[]='b' s1:=append(slice,) s1[]='b' fmt.Printf("%v",s1) }…
大家好,今天将梳理出的 Go语言基础语法内容,分享给大家. 请多多指教,谢谢. 本次<Go语言基础语法内容>共分为三个章节,本文为第一章节 Golang 基础之基础语法梳理 (一) Golang 基础之基础语法梳理 (二) Golang 基础之基础语法梳理 (三) 本章节内容 Go关键字 示例Demo 声明.赋值 引用类型 slice map Go关键字 Go语言中共有25个关键字,基础语法章节中将为大家介绍全部关键字的使用. break default func interface sele…
目录 当我们在说 slice 时,到底在说什么 slice 的创建 直接声明 字面量 make 截取 slice 和数组的区别在哪 append 到底做了什么 为什么 nil slice 可以直接 append 传 slice 和 slice 指针有什么区别 总结 参考资料 Go 语言的 slice 很好用,不过也有一些坑.slice 是 Go 语言一个很重要的数据结构.网上已经有很多文章写过了,似乎没必要再写.但是每个人看问题的视角不同,写出来的东西自然也不一样.我这篇会从更底层的汇编语言去解…
Golang 中的指针 - Pointer Go 的原生数据类型可以分为基本类型和高级类型,基本类型主要包含 string, bool, int 及 float 系列,高级类型包含 struct,array/slice,map,chan, func .   相比 Java,Python,Javascript 等引用类型的语言,Golang 拥有类似C语言的指针这个相对古老的特性.但不同于 C 语言,Golang 的指针是单独的类型,而不是 C 语言中的 int 类型,而且也不能对指针做整数运算.…