Go 在数组子切片上的内置范围具有不一致的行为

Posted

技术标签:

【中文标题】Go 在数组子切片上的内置范围具有不一致的行为【英文标题】:Go's built-in range on a sub-slice of an array has incongruent behavior 【发布时间】:2021-12-19 04:20:27 【问题描述】:

为什么我们不能使用内置的range 来指定给定数组索引的下限,但我们可以指定索引的上限?

给定一个 int 切片:

array := []int4, 76, -29, 3, 9, 223, 0, -3, -44, 76, 3, 98, 62, 144

我想在切片上进行范围,不包括前两个元素。

我可以用 for 循环做到这一点:

for i := 2; i < len(array); i++ 
        fmt.Printf("%d ", array[i])
    

但不能用内置的range

for i := range array[2:] 
        fmt.Printf("%d ", array[i])
    

奇怪的是,我可以排除上限范围内的元素,如下所示:

for i := range array[:5] 
        fmt.Printf("%d ", array[i])
    

在Go Playground上运行它

这是为什么?

【问题讨论】:

您的代码不包含任何数组。也许重做 Tour of Go 以刷新您对切片和数组以及 for 循环如何工作的记忆可能是一个好主意。 我只是交替使用术语数组和切片,可能不应该。 【参考方案1】:

表达式 array[2:] 计算为新的切片值。问题是应用程序假定新切片中的元素与array 中的对应元素具有相同的索引。

这里有几种解决问题的方法。

使用范围值:

for _, v := range array[2:] 
   fmt.Printf("%d ", v)

索引到新切片:

s := array[2:]
for i := ranges s 
   fmt.Printf("%d ", s[i])

当像array[:5]一样从末尾开始切片时,新切片中的元素与array中的对应元素具有相同的索引。

【讨论】:

【参考方案2】:

它确实有效,你只是在看错误的切片。

表达式array[2:] 是从array 的第二个元素开始的新切片。该切片的第 0 个元素是原始切片的第 2 个元素。这样做,你会看到:

for i,value := range array[2:] 
        fmt.Printf("%d ", value)

i 的值范围从 0 到 len(array)-2。

【讨论】:

以上是关于Go 在数组子切片上的内置范围具有不一致的行为的主要内容,如果未能解决你的问题,请参考以下文章

Go语言的切片

Go语言专题:go语言切片

go语言学习--切片

Go 语言入门很简单 -- 7. Go Slices #私藏项目实操分享#

Go语言切片

GO切片