Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[勘误]反馈一个第一章第二节中关于slice扩容问题 #88

Closed
xs-cw opened this issue Feb 22, 2021 · 7 comments
Closed

[勘误]反馈一个第一章第二节中关于slice扩容问题 #88

xs-cw opened this issue Feb 22, 2021 · 7 comments
Assignees
Labels
bug Something isn't working

Comments

@xs-cw
Copy link

xs-cw commented Feb 22, 2021

问题描述
文中描述是基于go1.16之前版本扩容规则,1.16后扩容规则有所变动。题目举例已经不符合预期了。

func main(){
 var slice []int
 slice = append(slice, 1, 2, 3)// 此时cap(slice)为3,go1.16前为4
}

如何找到这个错误

  • 章节:
    常见数据结构实现原理中slice篇
  • 页码:

您认为应该如何?

图片
如果有可能,尽量提供图片。

其他补充信息

@xs-cw xs-cw added the bug Something isn't working label Feb 22, 2021
@RainbowMango
Copy link
Owner

谢谢提醒,1.16的变化我还没来得及看。

@RainbowMango
Copy link
Owner

@xs-cw 请问你是看的1.16源码吗?扫了一遍 1.16 release notes 没看到相关说明。

@xs-cw
Copy link
Author

xs-cw commented Mar 5, 2021

@RainbowMango 源码里有体现的,github上地址

@RainbowMango
Copy link
Owner

关于下面函数的描述,正确的是?
 func SliceExtend() {
-       var slice []int
-       s1 := append(slice, 1, 2, 3)
+       s := make([]int, 0, 10)
+       s1 := append(s, 1, 2, 3)
        s2 := append(s1, 4)

        fmt.Println(&s1[0] == &s2[0])
 }
 单选:
-- A: 函数操作nil切片会panic
+- A: append函数在操作切片s和s1时发生了扩容
 - B: 编译错误,不可以对切片元素取址
 - C: 函数输出 true
 - D: 函数输出 false

感谢@lzw5399 @xs-cw 两位提供的信息,计划如上修订。题目不再考察扩容的细节。

@RainbowMango
Copy link
Owner

修订将提供给出版社,不出意外会在第4次印刷地修订。欢迎继续指正。

@RainbowMango
Copy link
Owner

@RainbowMango 源码里有体现的,github上地址

@xs-cw 又仔细看了你列出的这个改动。
这个改动主要是解决append(s, 0, 0)append(append(s,0), 0) 这两个表达的行为差异。

它解释不了下面的代码行为:

// main.go
package main

import "fmt"

func main() {
	var slice []int
	s1 := append(slice, 1, 2, 3)
	fmt.Println(cap(s1))
}

上面代码在Go1.15中返回4, 在Go1.16中返回3
不管在Go1.15还是在Go1.16中,上面代码中的append操作只触发一次growslice,并且old.len == old.cap == 0。对于上面的代码而言,这个改动不会改变growslice的行为。

@51snail
Copy link

51snail commented Oct 20, 2022

应该是1.16的class_to_size发生了变化,新增了24,1.15var class_to_size = [_NumSizeClasses]uint16{0, 8, 16, 32...,1.16 var class_to_size = _NumSizeClasses]uint16{0, 8, 16, 24, 32,... , int64 占用 8 byte,总内存 正好3 * 8 = 24 byte。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants