兄弟连Go全栈与区块链课程共计22周学习时长,划分为9个学习阶段,即区块链主流语言-Go语言开发实战 、区块链后端技术体系-Go语言高并发和服务器开发、Go开发区块链公链(区块链密码学、分布式编程、共识算法、基本概念,Golan公链开发)、以-太坊与智能合约与DAPP开发、区块链分布式应用开发、区块链系统框架开发-超级账本与区块链3.0EOS 、比特币与EOS底层源码分析和高级企业级项目实战。
据悉,整个课程体系将企业招聘区块链相关岗位时最为关注的区块链开发语言-Go语言、密码学、加密共识算法及区块链开源开发经验等内容涵盖其中,课程内容由清华微软谷歌技术团队由浅及深,循序渐进讲解。
切片概述
切片可以理解为长度可以动态变化的数组
切片和数组的相同点1:通过下标来访问元素
切片和数组的相同点2:通过下标或range方式遍历元素
不同点是切片的长度不是固定的,你可以动态地向切片中追加新的元素
切片中可以容纳的元素个数成为容量,容量>=长度
你可以通过len(slice)和cap(slice)分别获取切片的长度和容量
通过make(type,len,cap)的方式你可以创建出自定义初始长度和容量的切片
在追加元素的过程中,如果容量不够用时,就存在动态扩容的问题
动态扩容采用的是倍增策略,即:新容量=2*旧容量
扩容后的切片会得到一片新的连续内存地址,所有元素的地址都会随之发生改变
创建切片
func demob1() {
//有类无类冒等三种方式创建出类型、值、长度、容量都相同的切片
var s1 []int = []int{0,1,2}
var s2 = []int{0,1,2}
s3 := []int{0,1,2}
//这里的初始长度和容量是相等的
//type=[]int,value=[0 1 2],len=3,cap=3
fmt.Printf("type=%T,value=%v,len=%d,cap=%d\n",s1,s1,len(s1),cap(s1))
fmt.Printf("type=%T,value=%v,len=%d,cap=%d\n",s2,s2,len(s2),cap(s2))
fmt.Printf("type=%T,value=%v,len=%d,cap=%d\n",s3,s3,len(s3),cap(s3))
//创建长度和容量都为3的切片
s4 := make([]int, 3)
fmt.Printf("type=%T,value=%v,len=%d,cap=%d\n", s4, s4, len(s4), cap(s4))
//创建3长度、4容量的切片
s5 := make([]int, 3, 4)
fmt.Printf("type=%T,value=%v,len=%d,cap=%d\n", s5, s5, len(s5), cap(s5))
}
向切片中追加新的元素
容量每突破一次就翻倍
每翻倍一次,切片就获得一片新的堆地址,每一个元素的地址也都随之发生变化
切片名称的栈地址是不会变的
func demob2() {
s := make([]int, 0)
s = append(s, 1)
//value=[1],len=1,cap=1,saddr=0xc04205c3e0,elemaddr=0xc042062080
fmt.Printf("value=%v,len=%d,cap=%d,saddr=%p,elemaddr=%p\n", s, len(s), cap(s),&s,&s[0])
s = append(s, 2)
//value=[1 2],len=2,cap=2,saddr=0xc04205c3e0,elemaddr=0xc0420620d0
fmt.Printf("value=%v,len=%d,cap=%d,saddr=%p,elemaddr=%p\n", s, len(s), cap(s),&s,&s[0])
s = append(s, 3)
//value=[1 2 3],len=3,cap=4,saddr=0xc04205c3e0,elemaddr=0xc0420600e0
fmt.Printf("value=%v,len=%d,cap=%d,saddr=%p,elemaddr=%p\n", s, len(s), cap(s),&s,&s[0])
s = append(s, 4)
//value=[1 2 3 4],len=4,cap=4,saddr=0xc04205c3e0,elemaddr=0xc0420600e0
fmt.Printf("value=%v,len=%d,cap=%d,saddr=%p,elemaddr=%p\n", s, len(s), cap(s),&s,&s[0])
s = append(s, 5)
//value=[1 2 3 4 5],len=5,cap=8,saddr=0xc04205c3e0,elemaddr=0xc042088100
fmt.Printf("value=%v,len=%d,cap=%d,saddr=%p,elemaddr=%p\n", s, len(s), cap(s),&s,&s[0])
s = append(s, 6, 7, 8)
//value=[1 2 3 4 5 6 7 8],len=8,cap=8,saddr=0xc04205c3e0,elemaddr=0xc042088100
fmt.Printf("value=%v,len=%d,cap=%d,saddr=%p,elemaddr=%p\n", s, len(s), cap(s),&s,&s[0])
s = append(s, 9)
//value=[1 2 3 4 5 6 7 8 9],len=9,cap=16,saddr=0xc04205c3e0,elemaddr=0xc042092080
fmt.Printf("value=%v,len=%d,cap=%d,saddr=%p,elemaddr=%p\n", s, len(s), cap(s),&s,&s[0])
}
兼并其它切片
func demob3() {
s := make([]int, 0)
s = append(s, 1, 2, 3)
s2 := []int{4, 5, 6}
//追加s2中所有元素到s,注意这里的写法
s = append(s, s2...)
fmt.Println("s=",s)
fmt.Println("s2=",s2)
}
截取数组或切片,获得切片
截取方式:son := father[start:end]
start不写默认从开头截取
end不写默认截取到末尾
func demob4() {
var a [10]int = [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
//在数组的基础上截取,得到切片
as1 := a[2:8]
fmt.Printf("type=%T,value=%v\n", as1, as1)
//截取的方式[头下标:尾下标],含头不含尾,不写头默认头=0,不写尾默截取到最后一位
as2 := a[:8]
as3 := a[2:]
as4 := a[:]
fmt.Println(as2, as3, as4)
}
一开始切片引用底层数组的元素地址——切片和数组内容的修改会相互影响
切片扩容到突破原有容量时,就拷贝内容到新的地址——此时就已经完全脱离了底层数组
func demob5() {
var a [10]int = [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
//切片不是值拷贝,而是直接底层数组地址
as1 := a[:5]
as2 := as1[:]
//[0 1 2 3 4] [0 1 2 3 4]
fmt.Println(as1, as2)
//0xc0420140a0,0xc0420140a0,0xc0420140a0
fmt.Printf("%p,%p,%p\n", &a[0], &as1[0], &as2[0])
//切片不是值拷贝,而是直接底层数组地址
as1[0] = 123
as2[1] = 38
//[123 38 2 3 4 5 6 7 8 9] [123 38 2 3 4] [123 38 2 3 4]
fmt.Println(a, as1, as2)
//扩容突破了容量(cap)的上限,切片拷贝得到新的元素地址,脱离了原先的底层数组
//before:cap=10,addr=0xc04205c3e0,elemaddr=0xc042090000
fmt.Printf("before:cap=%d,addr=%p,elemaddr=%p\n", cap(as2), &as2, &as2[0])
as2 = append(as2, 666, 777, 888,999,1000,1100,1100)
//after:cap=20,addr=0xc04205c3e0,elem addr=0xc042094000
fmt.Printf("after:cap=%d,addr=%p,elemaddr=%p\n", cap(as2), &as2, &as2[0])
as2[0] = 90000
//打印的结果就是:as2脱离了a和as1,自成一家
fmt.Println(a, as1, as2)
a[0] = 0
fmt.Println(a, as1, as2)
}
拷贝src切片,覆盖dst切片
func demob6() {
//var dst = []int{1,2,3,4}
//var src = []int{10,20,30,40}
//var dst = []int{1,2,3,4}
//var src = []int{10,20,30,40,50}
var dst = []int{1, 2, 3, 4, 5, 6}
var src = []int{10, 20, 30, 40}
//src中的元素从头覆盖dst中的元素,返回受影响的元素个数
n := copy(dst, src)
fmt.Println(dst, n)
}
遍历访问切片元素
func demob7() {
s := make([]int, 0)
s = append(s, 10, 20, 30, 40, 50)
for index, value := range s {
fmt.Println(index, value)
}
}
更多区块链视频教程/源码/课件/学习资料-企鹅QUN:591229276
有疑问加站长微信联系(非本文作者)