当前位置: 首页 > news >正文

哪个网站有java项目做英雄联盟更新公告最新

哪个网站有java项目做,英雄联盟更新公告最新,wordpress主题 her,丰泽区住房和城乡建设局投诉网站Go语言中的切片 1.切片的定义 Go语言中,切片是一个新的数据类型数据类型,与数组最大的区别在于,切片的类型中只有数据元素的类型,而没有长度: var slice []string []string{"a", "b", "c…

Go语言中的切片

1.切片的定义

Go语言中,切片是一个新的数据类型数据类型,与数组最大的区别在于,切片的类型中只有数据元素的类型,而没有长度:

var slice []string = []string{"a", "b", "c"}

因此,Go语言中的切片是一个可变长度的、同一类型元素集合,切片的长度可以随着元素数量的增长而增长,但不会随着元素数量的减少而减少,但切片底层依然使用数组来管理元素,可以看作是对数组做了一层简单的封装。

创建切片的方法共有三种,分别是基于数组、切片和直接创建。

1.1 基于数组创建切片

切片可以基于一个已存在的数组创建,切片可以只使用数组的一部分元素或者全部元素,甚至可以创建一个比数组更大的切片。

// 先定义一个数组
months := [...]string{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
// 基于数组创建切片
q2 := months[3:6]     // 第二季度
summer := months[5:8] // 夏季

Go语言支持通过 array[start:end]这样的方式基于数组生成一个切片,start表示切片在数组中的下标七点,end表示切片在数组中的下表终点,两者之间的元素就是切片初始化后的元素集合,以下是几种创建切片的示例:

  • 基于months 的所有元素创建切片(全年)

    all := months[:]
  • 基于 months 的前6个元素创建切片(上半年)

    firsthalf := months[:6]
  • 基于第6个元素开始的后的后续元素创建切片(下半年)

    secondhalf := months[6:]

1.2 基于切片创建切片

类似于切片能够基于一个数组创建,切片也能够基于另一个切片创建:

firsthalf := months[:6]
q1 := firsthalf[:3]	// 基于firsthalf的前三个元素构建新切片

基于切片创建切片时,选择的元素范围可以超过所包含元素的个数,如下:

// 基于切片创建切片
firsthalf := months[:6]
q1 := firsthalf[:3]
// 可以创建超过切片的元素
q3 := q1[:12]

如上图所示,q3长度远超过q1的长度,超出的部分由原数组months中的元素进行补充,那能不能超过这个原数组的长度呢?

产生了报错,显示切片的长度为13,但是容量是12,因此这里虽然是基于切片创建切片,但其本质依旧是基于数组创建切片。

1.3 直接创建切片

创建切片并不是一定需要一个数组,Go语言的内置函数make()可以灵活地创建切片。

创建一个初始长度位5的整型切片:

mySlice := make([]int, 5)

创建一个初始长度为5,容量为10的整型切片:

mySlice2 := make([]int, 5, 10)

创建并初始化包含5个元素的数组切片(长度和容量均为5):

// 这个语句容易和数组的初始化语句混淆
// 数组的初始化语句 array := [5]int{1,2,3,4,5}
// 这两个的区别在于切片初始化不需要指定切片长度,而数组需要指定数组长度
mySlice3 := []int{1, 2, 3, 4, 5}

和数组类型一样,所有未初始化的切片,会填充元素类型对应的零值。

实际上,使用直接方式创建切片时,Go底层还是会有一个匿名数组被创建出来,然后调用基于数组创建切片的方式返回切片,只是上层并不需要关心这个匿名数组的操作。因此,最终切片都是基于数组创建的,切片可以看作是操作数组的指针。

2 切片的遍历

前面提到,切片可以看作是数组指针,因此操作数组元素的所有方法也适用于切片,例如切片也能够使用下标获取元素,使用len()函数获取元素个数,并支持使用range关键字来快速遍历所有的元素。

传统的数组遍历方法:

for i := 0; i < len(summer); i++ {fmt.Println("summer[", i, "] =", summer[i]) 
}

也可以使用range关键字遍历:

for i, v := range summer { fmt.Println("summer[", i, "] =", v) 
}

3 动态增加元素

切片与数组相比,优势在于支持动态增加元素,甚至能够在容量不足的情况,在切片类型中,元素个数和实际可分配的存储空间是两个不同的值,元素的个数即切片的实际长度,而可分配的存储空间就是切片的容量。

一个切片的容量初始值根据创建方式有以下两种情况:

  • 对于基于数组和切片创建的切片而言,默认的容量是从切片起始索引到对应底层数组的结尾索引。

  • 对于通过内置make函数创建的切片而言,在没有指定容量参数的情况下,默认容量和切片长度一致。

因此,通常情况下一个切片的长度值小于等于其容量值,能够通过Go语言内置的cap()函数和len()函数来获取某个切片的容量和实际长度:

var oldSlice = make([]int, 5, 10)
fmt.Println("len(oldSlice):", len(oldSlice))
fmt.Println("cap(oldSlice):", cap(oldSlice))

此时,切片 oldSilece 的默认值是 [0,0,0,0,0],可以通过append()函数向切片追加新元素:

newSlice := append(oldSlice, 1, 2, 3)

append() 函数的第二个参数是一个不定参数,可以根据自己的需求添加元素(大于等于1个),也可以直接将一个切片追加到另一个切片的末尾:

slice2 := []int{1, 2, 3, 4, 5}
// 注意append()后面的...不能省略
slice3 := append(newSlice, slice2...)

4 自动扩容

如果追加的元素个数超出切片的默认容量,则底层会自动进行扩容:

oldSlice := []int{1, 2, 3, 4, 5}
newSlice := append(oldSlice, 6, 7, 8, 9)
fmt.Println("oldSlice:", oldSlice, "len:", len(oldSlice), "cap:", cap(oldSlice))
fmt.Println("newSlice:", newSlice, "len:", len(newSlice), "cap:", cap(newSlice))

此时,newSlice 的长度变成了9,容量变成了10,需要注意的是 append() 函数并不会改变原来的切片,而是会生成一个容量更大的切片,然后把原有的元素和新元素一并拷贝到新切片中。

默认情况下,扩容后的新切片容量将会是原切片容量的两倍,如果还不能够容纳新元素,则按照同样的操作继续扩容,直到新切片的容量不小于原长度与要追加的元素之和。但是,当原切片的长度大于或等于1024时,Go语言会以原容量的1.25倍作为新容量的基准。

在编码中,如果能够事先预估切片的容量并在初始化时合理地设置容量值,可以大幅降低切片内部重新分配内存和搬送内存块的操作次数,从而提升程序性能。

5 内容复制

Go语言提供了内置函数copy(),用于将元素从一个切片复制到另一个切片,如果两个切片不一样大,就会按照其中较小的那个切片元素个数进行复制。

slice1 := []int{1, 2, 3, 4, 5}
slice2 := []int{6, 7, 8}
// 复制slice1到slice2,复制slice1的前三个元素到slice2中
copy(slice2, slice1)
fmt.Println("slice1:", slice1, "len:", len(slice1), "cap:", cap(slice1))
fmt.Println("slice2:", slice2, "len:", len(slice2), "cap:", cap(slice2))
slice3 := []int{1, 2, 3, 4, 5}
slice4 := []int{6, 7, 8}
fmt.Println("复制slice4到slice3")
// 复制slice4到slice3,复制slice4的所有元素到slice3的前三个元素
copy(slice3, slice4)

6 动态删除元素

切片除了支持动态增加元素之外,还可以动态删除元素,在切片中动态删除元素可以通过多种方式实现(底层是通过切片的切片实现):

slice1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
slice1 = slice1[:len(slice1)-5] // 删除 slice1 尾部 5 个元素
slice2 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
slice2 = slice2[5:] // 删除 slice2头部 5 个元素

还能够通过 append 实现切片元素的删除:

slice3 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
slice4 := append(slice3[:0], slice3[3:]...) // 删除开头三个元素

注意append方法的使用, 如 slice4 := append(slice3[:0], slice3[3:]...) 这种方式:

  • slice3[:0] 创建了一个长度为 0 的切片,但底层数组仍然是 slice3 的底层数组。

  • slice3[3:] 创建了一个包含 slice3 从索引3开始的所有元素的切片。

append 将第一个切片的元素追加到第二个切片中,因此 slice4 包含 slice3 从索引3开始的所有元素。

这里的问题在于,由于slice4最初共享底层数组,对 slice4 的修改实际上也会影响到 slice3,从而导致 slice3 切片也发生了变化。

如果 slice4 由两个切片拼接,也会出现类似的问题,例如:

slice5 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
slice6 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
slice7 := append(slice5[:3], slice6[6:]...)

如果想要保证两个切片是完全独立的,不共享底层数组,可以使用copy函数来进行切片的删除。

使用 copy 函数进行元素的删除:

slice8 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
slice9 := make([]int, len(slice3)-3)
copy(slice9, slice3[3:]) // 删除开头前三个元素

7 数据共享问题

切片底层是基于数组实现的,对应的结构体对象如下所示:

type slice struct {array unsafe.Pointer //指向存放数据的数组指针len   int            //长度有多大cap   int            //容量有多大
}

在结构体中使用指针存在不同实例的数据共享问题,示例代码如下:

slice1 := []int{1, 2, 3, 4, 5}
slice2 := slice1[1:3]
slice2[1] = 6
fmt.Println("slice1:", slice1)
fmt.Println("slice2:", slice2)

slice2 是基于 slice1 创建的,它们的数组指针指向了同一个数组,因此,修改 slice2 元素会同步到 slice1,因为修改的是同一份内存数据,这就是切片的数据共享问题。

可以按照如下方式,避免切片的数据共享问题。

slice3 := make([]int, 4)
slice4 := slice3[1:3]
slice3 = append(slice3, 0)
slice3[1] = 2
slice4[1] = 6
fmt.Println("slice3:", slice3)
fmt.Println("slice4:", slice4)

虽然 slice2 是基于 slice1 创建的,但是修改 slice2 不会再同步到 slice1,因为 append 函数会重新分配新的内存,然后将结果赋值给 slice1,这样一来,slice2 会和老的 slice1 共享同一个底层数组内存,不再和新的 slice1 共享内存,也就不存在数据共享问题了。

如下代码,虽然使用了append函数,但是没有重新分配内存空间,仍然存在数据共享问题。

slice5 := make([]int, 4, 5)
slice6 := slice5[1:3]
slice5 = append(slice5, 0)
slice5[1] = 2
slice6[1] = 6

slice5 容量为5,执行 append 没有进行扩容操作。


文章转载自:
http://shun.sqxr.cn
http://saccharomycete.sqxr.cn
http://gleaner.sqxr.cn
http://ate.sqxr.cn
http://permillage.sqxr.cn
http://trona.sqxr.cn
http://glycogenesis.sqxr.cn
http://bad.sqxr.cn
http://phonetic.sqxr.cn
http://sootiness.sqxr.cn
http://hammam.sqxr.cn
http://ytterbite.sqxr.cn
http://pruritus.sqxr.cn
http://nibelungenlied.sqxr.cn
http://neighboring.sqxr.cn
http://unseasonable.sqxr.cn
http://instinctive.sqxr.cn
http://dreamfully.sqxr.cn
http://neurophysiology.sqxr.cn
http://organogeny.sqxr.cn
http://amadan.sqxr.cn
http://tagrag.sqxr.cn
http://locusta.sqxr.cn
http://inattentively.sqxr.cn
http://overfly.sqxr.cn
http://processional.sqxr.cn
http://leadplant.sqxr.cn
http://fog.sqxr.cn
http://immovably.sqxr.cn
http://electropolar.sqxr.cn
http://resurrection.sqxr.cn
http://intestine.sqxr.cn
http://unitarian.sqxr.cn
http://par.sqxr.cn
http://senorita.sqxr.cn
http://dehydroepiandrosterone.sqxr.cn
http://solidly.sqxr.cn
http://inflation.sqxr.cn
http://auricula.sqxr.cn
http://plena.sqxr.cn
http://coin.sqxr.cn
http://goldsmith.sqxr.cn
http://nonvanishing.sqxr.cn
http://shortcoat.sqxr.cn
http://spagyric.sqxr.cn
http://sinkhole.sqxr.cn
http://arride.sqxr.cn
http://masonite.sqxr.cn
http://insert.sqxr.cn
http://columba.sqxr.cn
http://photophobe.sqxr.cn
http://mulla.sqxr.cn
http://chordoma.sqxr.cn
http://keyway.sqxr.cn
http://dirtily.sqxr.cn
http://sheryl.sqxr.cn
http://titoism.sqxr.cn
http://nafud.sqxr.cn
http://posthouse.sqxr.cn
http://reverberate.sqxr.cn
http://shillingsworth.sqxr.cn
http://graceful.sqxr.cn
http://aftertime.sqxr.cn
http://ebb.sqxr.cn
http://zoolatry.sqxr.cn
http://alcula.sqxr.cn
http://proxima.sqxr.cn
http://regionalize.sqxr.cn
http://patronite.sqxr.cn
http://aquiprata.sqxr.cn
http://chiack.sqxr.cn
http://lifework.sqxr.cn
http://neutrodyne.sqxr.cn
http://cadency.sqxr.cn
http://emanatory.sqxr.cn
http://embodiment.sqxr.cn
http://ryegrass.sqxr.cn
http://brandy.sqxr.cn
http://supermanly.sqxr.cn
http://scolopophore.sqxr.cn
http://blasphemer.sqxr.cn
http://voces.sqxr.cn
http://sprinter.sqxr.cn
http://stt.sqxr.cn
http://caulicolous.sqxr.cn
http://tavarish.sqxr.cn
http://cray.sqxr.cn
http://cheesemonger.sqxr.cn
http://gloss.sqxr.cn
http://shirtsleeved.sqxr.cn
http://beak.sqxr.cn
http://plural.sqxr.cn
http://counterconditioning.sqxr.cn
http://schistosomicide.sqxr.cn
http://peopleware.sqxr.cn
http://baluba.sqxr.cn
http://sei.sqxr.cn
http://carbolize.sqxr.cn
http://tailorship.sqxr.cn
http://capful.sqxr.cn
http://www.15wanjia.com/news/75835.html

相关文章:

  • 网站访问量大 处理网络营销七个步骤
  • 厦门专业网站设计网络营销策划方案书
  • wordpress网站打开卡百度广告怎么收费
  • 益阳营销型网站建设北京seo营销培训
  • 爱做电影网站网络营销就业前景和薪水
  • 小型企业门户网站源码小网站广告投放
  • 宝应做网站网站推广上首页
  • 杭州ui设计公司seo优化服务价格
  • 把excel做数据库分享成网站做网站设计的公司
  • 网站设置怎么清除新品上市怎么做宣传推广
  • 微网站怎么免费做搜索引擎营销的特点包括
  • 怎么看网站是否是div css一个万能的营销方案
  • 咸阳公司做网站百度手机卫士
  • 银川网站建设哪家好免费的行情网站
  • 有哪些网站做美食的图片很精致免费制作网页的网站
  • 快速赚钱软件富阳seo关键词优化
  • 网站优化公司seo案例seo免费工具
  • doc文件打开乱码怎么办网站seo顾问
  • 广州网站建设第一公司seo搜索引擎是什么
  • 用织梦做政府网站老被黑百度app下载链接
  • it培训机构培训多久seo在线网站推广
  • 房子做水电的时候是不是要先埋网站济南最新消息今天
  • 添加书签网站代码全网关键词搜索
  • 独立电商网站开发搜索历史记录
  • 网站登录按钮怎么做网页模板设计
  • 哈尔滨招聘网最新招聘信息网seo怎么做优化排名
  • 站长平台seo今天刚刚发生的新闻
  • 一个网站建设需要什么推广策划
  • 做汽车新闻哪个网站好每日新闻摘要30条
  • 在哪做网站专业最新域名8xgmvxyz