【建站服务】嘉兴网站建设_企业网站制作公司_高端网站设计开发-嘉兴上往-域名申请
作者: 风兰 . 阅读量: 2 . 发表时间:2022-09-21 05:52:51
上往建站提供服务器空间服务商,百度快照排名,网站托管,百度推广运营,致力于设计外包服务与源代码定制开发,360推广,搜狗推广,增加网站的能见度及访问量提升网络营销的效果,主营:网站公司,百度推广公司电话,官网搭建服务,网站服务企业排名,服务器空间,英文域名等业务,专业团队服务,效果好。
嘉兴网站建设_企业网站制作公司_高端网站设计开发-嘉兴上往

、
断,如果旧切片的长度小于1024,则最终容量(newcap)就是旧容量(old.cap)的两倍,即(newcap=doublecap),
否则判断,如果旧切片长度大于等于1024,则最终容量(newcap)从旧容量(old.cap)开始循环增加原来的1/4,即(newcap=old.cap,for {newcap += newcap/4})直到最终容量(newcap)大于等于新申请的容量(cap),即(newcap >= cap)
如果最终容量(cap)计算值溢出,则最终容量(cap)就是新申请容量(cap)。
需要注意的是,切片扩容还会根据切片中元素的类型不同而做不同的处理,比如int和string类型的处理方式就不一样。
是小飞呀
是小飞呀
211***3262@qq.com
参考地址
2年前 (2020-08-18)
dopsie
850***208@qq.com
6
楼上对于扩容后的容量说明都在发生扩容的代码逻辑中,没有说明这段代码中的参数 cap(申请容量) 是怎么计算的 。
经过多次的测试,我这边猜测是在 append 发生扩容时,申请容量是 原切片容量 + 追加的长度,如果是单数则 +1,再将这个容量传入扩容的方法进行判断,以讨论的 cap 变为6的代码为例:
原切片为 []int{1, 2} ,长度为2(记为 len1 = 2),容量为2(记为 cap1 =2)。
追加的长度为 {3, 4, 5},长度为3(记为 len2= 3),此时进行扩容,申请容量为6(记为 cap2 = cap1+len2,cap2 为单数,则+1,cap2 = 6),将 cap2 带入楼上的扩容判断逻辑。
申请容量 cap2 大于2倍的旧容量(cap1 = 2),则newcap = cap2 = 6
部分测试打印如下:
len=0 cap=0 slice=[]
len=2 cap=2 slice=[0 1] // len1 = 2,cap1 = 2
len=5 cap=6 slice=[0 1 2 3 4] // len2 = 3,cap2 = cap1+len2 = 5,单数+1,cap2 = 6
len=0 cap=0 slice=[]
len=2 cap=2 slice=[0 1] // len1 = 2,cap1 = 2
len=6 cap=6 slice=[0 1 2 3 4 5] // len2 = 3,cap2 = cap1+len2 = 6
dopsie
dopsie
850***208@qq.com
2年前 (2021-01-26)
多喝热水
610***322@qq.com
2
关于 append 会让切片与其他相关切片脱钩的问题:
package main
import "fmt"
func main() {
x := make([]int, 4)
a := x[:2]
a[0] = 1
fmt.Println(a)
fmt.Println(x)
a = append(a, 2)
a[0] = 0
fmt.Println(a)
fmt.Println(x)
fmt.Printf("切片a的地址:%p ", a)
fmt.Printf("切片x的地址:%p ", x)
fmt.Println()
y := make([]int, 4)
b := y
b[0] = 1
fmt.Println(b)
fmt.Println(y)
b = append(b, 2)
b[0] = 0
fmt.Println(b)
fmt.Println(y)
fmt.Printf("切片b的地址:%p ", b)
fmt.Printf("切片y的地址:%p ", y)
fmt.Println()
}
嘉兴网站建设_企业网站制作公司_高端网站设计开发-嘉兴上往
上往建站提供搭建网站,域名注册,官网备案服务,网店详情页设计,企业网店,专业网络店铺管理运营全托管公司咨询电话,服务器空间,微信公众号托管,网页美工排版,致力于域名申请,竞价托管,软文推广,全网营销,提供标准级专业技术保障,了却后顾之忧,主营:虚拟主机,网站推广,百度竞价托管,网站建设,上网建站推广服务,网络公司有哪些等业务,专业团队服务,效果好。
服务热线:400-111-6878 手机微信同号:18118153152(各城市商务人员可上门服务)
关键词:网站建设,企业网站,网站制作,网页设计,高端网站建设,企业网站制作,网页制作,制作网站,网站设计,高端网页设计,高端网站设计,做网站,自适应网站



为什么这里的 cap 不是 5 呢?
要弄清楚这个问题,先要理解如下代码:
// 每次cap改变,指向array的ptr就会变化一次s := make([]int, 1)fmt.Printf("len:%d cap: %d array ptr: %v ", len(s), cap(s), *(*unsafe.Pointer)(unsafe.Pointer(&s)))for i := 0; i < 5; i++ { s = append(s, i) fmt.Printf("len:%d cap: %d array ptr: %v ", len(s), cap(s), *(*unsafe.Pointer)(unsafe.Pointer(&s)))}fmt.Println("Array:", s)以上代码执行输出结果为:
解释:每次cap改变的时候指向array内存的指针都在变化。当在使用 append 的时候,如果 cap==len 了这个时候就会新开辟一块更大内存,然后把之前的数据复制过去(实际go在append的时候放大cap是有规律的。在 cap 小于1024的情况下是每次扩大到 2 * cap ,当大于1024之后就每次扩大到 1.25 * cap 。所以上面的测试中cap变化是 1, 2, 4, 8)。
网友小王
770***908@qq.com
是小飞呀
211***3262@qq.com
参考地址
可以通过查看$GOROOT/src/runtime/slice.go源码,其中扩容相关代码如下:
newcap := old.cap doublecap := newcap + newcapif cap > doublecap { newcap = cap} else { if old.len < 1024 { newcap = doublecap } else { // Check 0 < newcap to detect overflow // and prevent an infinite loop. for 0 < newcap && newcap < cap { newcap += newcap / 4 } // Set newcap to the requested cap when // the newcap calculation overflowed. if newcap <= 0 { newcap = cap } }}从上面的代码可以看出以下内容:
需要注意的是,切片扩容还会根据切片中元素的类型不同而做不同的处理,比如
int和string类型的处理方式就不一样。是小飞呀
211***3262@qq.com
参考地址
首先判断,如果新申请容量(cap)大于2倍的旧容量(old.cap),最终容量(newcap)就是新申请的容量(cap)。
否则判断,如果旧切片的长度小于1024,则最终容量(newcap)就是旧容量(old.cap)的两倍,即(newcap=doublecap),
否则判断,如果旧切片长度大于等于1024,则最终容量(newcap)从旧容量(old.cap)开始循环增加原来的1/4,即(newcap=old.cap,for {newcap += newcap/4})直到最终容量(newcap)大于等于新申请的容量(cap),即(newcap >= cap)
如果最终容量(cap)计算值溢出,则最终容量(cap)就是新申请容量(cap)。
dopsie
850***208@qq.com
楼上对于扩容后的容量说明都在发生扩容的代码逻辑中,没有说明这段代码中的参数 cap(申请容量) 是怎么计算的 。
经过多次的测试,我这边猜测是在 append 发生扩容时,申请容量是 原切片容量 + 追加的长度,如果是单数则 +1,再将这个容量传入扩容的方法进行判断,以讨论的 cap 变为6的代码为例:
原切片为 []int{1, 2} ,长度为2(记为 len1 = 2),容量为2(记为 cap1 =2)。
追加的长度为 {3, 4, 5},长度为3(记为 len2= 3),此时进行扩容,申请容量为6(记为 cap2 = cap1+len2,cap2 为单数,则+1,cap2 = 6),将 cap2 带入楼上的扩容判断逻辑。
申请容量 cap2 大于2倍的旧容量(cap1 = 2),则newcap = cap2 = 6