当前位置:  开发笔记 > 编程语言 > 正文

在Go切片中,为什么s [lo:hi]在元素hi-1处结束?

如何解决《在Go切片中,为什么s[lo:hi]在元素hi-1处结束?》经验,为你挑选了1个好方法。

根据围棋的游,在围棋切片s,表达式s[lo:hi]的计算结果为从元件的切片lo通过hi-1,包括:

package main

import "fmt"

func main() {

    p := []int{0,  // slice position 0 
               10, // slice position 1
               20, // slice position 2
               30, // slice position 3
               40, // slice position 4
               50} // slice position 5

    fmt.Println(p[0:3]) // => [0 10 20]
}    

在我上面的代码示例中,"p [0:3]"似乎直观地"读取"为:"从位置0到位置3的切片",等于[0,10,20,30].但当然,它实际上相当于[0 10 20].

所以我的问题是:评估上限值的设计原理是什么hi-1而不是简单hi?这感觉不直观,但必须有一些理由让我失踪,我很好奇这可能是什么.

提前致谢.



1> joshlf..:

这完全是一个惯例问题,当然还有其他方法(例如,Matlab使用第一个索引为1的数组).选择真正归结为您想要的属性.事实证明,使用0索引数组,其中切片是包容性的(即,从a到b的切片包括元素a并且排除元素b)具有一些非常好的属性,因此它是一种非常常见的选择.这里有一些优点.

0索引数组和包容性独占切片的优点

(请注意,我使用的是非Go术语,所以我将以C或Java谈论它们的方式讨论数组.数组是Go调用切片,切片是子数组(即"切片")从索引1到索引4"))

指针算术工作.如果您使用的是C语言,那么数组实际上只是指向数组中第一个元素的指针.因此,如果使用0索引数组,那么可以说索引i处的元素只是数组指针加i指向的元素.例如,如果我们有数组[3 2 1],数组的地址为10(假设每个值占用一个字节的内存),那么第一个元素的地址是10 + 0 = 10,第二个的地址是10 + 1 = 11,依此类推.简而言之,它使数学简单.

切片的长度也是切片的位置.也就是说,对于一个数组来说arr,arr[0:len(arr)]就是它arr本身.这在实践中很方便.例如,如果我调用n, _ := r.Read(arr)(n读入的字节数在哪里arr),那么我就arr[:n]可以获得与arr实际写入的数据相对应的切片arr.

指数不重叠.这意味着,如果我有arr[0:i],arr[i:j],arr[j:k],arr[k:len(arr)],这些片完全覆盖arr本身.您可能不会经常发现自己将数组划分为这样的子切片,但它具有许多相关的优点.例如,请考虑以下代码以基于非连续整数拆分数组:

func consecutiveSlices(ints []int) [][]int {
    ret := make([][]int, 0)
    i, j := 0, 1
    for j < len(ints) {
        if ints[j] != ints[j-1] + 1 {
            ret = append(ret, ints[i:j])
            i = j
        }
    }
    ret = append(ret, ints[i:j])
}

(这段代码显然不能很好地处理一些边缘情况,但你明白了)

如果我们尝试使用包容性包含切片来编写等效函数,那将会更加复杂.

如果有人再想一想,请随时编辑此答案并添加它们.

推荐阅读
Gbom2402851125
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有