英文:
golang make 0 length slice and re-slicing slice not as expected
问题
我看到这段代码感到困惑,请帮我解释一下。
这段代码的作用是:
package main
import "fmt"
func main() {
s := make([]int, 0, 10)
s1 := s[0:1]
s1[0] = 1
println("-----")
fmt.Println(s1, len(s1), cap(s1)) //[1] 1 10
fmt.Println(s, len(s), cap(s)) //[] 0 10
fmt.Println(s, s[0:10]) // [] [1 0 0 0 0 0 0 0 0 0]
}
上述程序可以完美执行,但打印的值不符合我的预期,我有两个问题:
-
为什么在
fmt.Println(s1, len(s1), cap(s1))
和fmt.Println(s, len(s), cap(s))
中,s1 的打印值是 [1],而 s 的打印值是 []。我认为 s1 的值应该等于 s 的值,都是 [1]。 -
为什么 s[0:10] 可能打印出 [1 0 0 0 0 0 0 0 0 0],而 s 打印的是 []。我认为 s[0:10] 是对 s 进行重新切片,如果 s 是 [],那么 s[0:10] 也应该是 []。
英文:
I saw this code feel confusing,please help me explain.
the code:
package main
import "fmt"
func main() {
s := make([]int, 0, 10)
s1 := s[0:1]
s1[0] = 1
println("-----")
fmt.Println(s1, len(s1), cap(s1)) //[1] 1 10
fmt.Println(s, len(s), cap(s)) //[] 0 10
fmt.Println(s, s[0:10]) // [] [1 0 0 0 0 0 0 0 0 0]
}
The above program can be executed perfectly,While print value is not meet my expectations,I have two questions:
-
why s1 print value is: [1], while s print value is [] in the
fmt.Println(s1, len(s1), cap(s1))
andfmt.Println(s, len(s), cap(s))
. I think s1 value is equal to s value is [1]. -
why s[0:10] may print [1 0 0 0 0 0 0 0 0 0], while s print []. I think s[0:10] is re-slice of s,if s is [], s[0:10] is [] too.
答案1
得分: 1
s1
打印出[1]
,因为它是一个长度为1的切片,并且在这个长度内有元素1。它的长度为1,是因为它是从s
的索引0
到1
的切片。因此,s1 := s[0:1]
。s
打印出[]
,因为它是一个长度为0的切片。当长度为0时,没有值可以显示,所以在方括号中没有任何内容。它的长度为0是因为在make
函数调用中指定了长度为0。在使用make
创建切片时,第二个参数是切片的长度。s[0:10]
可能打印出[1 0 0 0 0 0 0 0 0 0]
,因为可以将现有的切片重新切片为其整个底层数组的容量,而不仅仅是长度。由于重新切片从0
到10
,它将包含10个值(切片的第二个边界是不包含的)。这就是为什么在打印输出中看到了所有10个值。- 作为额外的说明,
s[0:10]
不能是[]
,因为这意味着你指定了一个长度为10的切片,但返回的却是一个长度为0的切片。在 Go 语言中,切片s[a:b]
的长度始终为b - a
。如果这不可能,程序将会引发错误。它不会给你一个其他长度的切片。请参阅语言规范中关于这些规则的解释:https://go.dev/ref/spec#Slice_expressions
英文:
s1
prints[1]
because it is a slice of length 1, and it has the element 1 within that length. It is length 1 because it is a slice ofs
from0
to1
. Hence,s1 := s[0:1]
s
prints the value[]
because it is a slice of length 0. There are no values to show when the length is 0, so there is nothing between the brackets. It is length 0 because it was specified as such in themake
call. When usingmake
to make a slice, the second argument is the length of the slice.s[0:10]
may print[1 0 0 0 0 0 0 0 0 0]
because it is allowed to re-slice an existing slice into its whole underlying capacity, not just the length. Since the re-slice goes from0
to10
, it will include 10 values (the second bound of the slice is non-inclusive). That's why you see all 10 values in the printout.- As a bonus point,
s[0:10]
cannot be[]
because that would mean you specify a slice of length 10 and get in return a slice of length 0. In Go, the length of a slices[a:b]
will always have a length ofb - a
. If that's not possible, then the program will panic. It will not give you a slice of some other length. See the explanation of these rules in the language specification: https://go.dev/ref/spec#Slice_expressions
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论