【问题标题】:Safely getting a subsection of a slice in Go在 Go 中安全地获取切片的一部分
【发布时间】:2017-08-10 13:07:30
【问题描述】:

我知道你可以在 Go via 中获得切片的一个小节

test := []int{0, 1, 2, 3, 4}
subsection := test[:2]

但是如果你尝试类似的东西

subsectionError := test[:10]

你会得到一个越界错误。目前我正在做类似的事情

length := 10
if len(test) < length {
    length = len(test)
}
safeSubsection := test[:length]

为了避免错误,但有更好的方法吗?我觉得这很 hacky,但话说回来,Go 通常似乎是一种非常明确的语言。

【问题讨论】:

  • 恕我直言,这是在 go 中执行此操作的方法。否则,“更好”、“hacky”听起来像是你在钓鱼,这主要是基于意见的。
  • 如何检查您是否正在“hacky”越界访问内存?这是内存安全语言的一部分,而不是依赖 SIGSEGV 来指示您不应该访问这些地址。
  • 您想要切片的某个切片但不知道或不关心原始切片的长度或生成的切片是否是您请求的长度也是一种罕见的情况。我猜这是为了截断字符串,在这种情况下我会使用fmt.Sprintf 而不是切片。

标签: go slice


【解决方案1】:

在 Go 中,答案通常是在函数或方法中隐藏丑陋。比如一个min函数,

package main

import "fmt"

func min(x, y int) int {
    if y < x {
        return y
    }
    return x
}

func main() {
    test := []int{0, 1, 2, 3, 4}
    fmt.Println(test)
    sub := test[:min(10, len(test))]
    fmt.Println(sub)
}

输出:

[0 1 2 3 4]
[0 1 2 3 4]

【讨论】:

    【解决方案2】:

    如果你发现自己经常这样做,并且丑陋让你烦恼,你可以制作一个切片类型,并在上面放置一些方便的方法。如果您有很多对列表进行操作的便捷方法(例如 min、max、head、contains 等),这将很有用。我使用它来将包含添加到字符串或 int 切片中。

    package main
    
    import (
        "fmt"
    )
    
    type Ints []int
    
    func (i Ints) Head(count int) Ints {
        if count > len(i) {
            count = len(i)
        }
        return i[:count]
    }
    
    
    func main() {
    
        test := Ints{0, 1, 2, 3, 4}
        fmt.Printf("First 2 %v\n", test.Head(2))
        fmt.Printf("First 10 %v\n", test.Head(10))
    }
    

    https://play.golang.org/p/OkCjHdlj0u

    如果你只做一次,那可能不值得付出努力,如果你有几个循环在同一个列表上运行,它可能是。当然,这是一个在 Go 中拥有更复杂的通用容器会很好的领域。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-12
      • 2019-12-22
      • 1970-01-01
      • 2021-04-29
      • 2015-04-10
      • 2018-02-15
      • 2016-08-10
      • 1970-01-01
      相关资源
      最近更新 更多