英文:
Safely getting a subsection of a slice in Go
问题
我知道在Go语言中,你可以通过以下方式获取切片的子切片:
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]
以避免错误发生。但是,是否有更好的方法来处理这个问题呢?对我来说,这种方法似乎有点笨拙,但是Go语言通常都是一种相当明确的语言。
英文:
I know that you can get a subsection of a slice in Go via
test := []int{0, 1, 2, 3, 4}
subsection := test[:2]
But if you try something like
subsectionError := test[:10]
You'll get an out of bounds error. Currently I'm doing something like
length := 10
if len(test) < length {
length = len(test)
}
safeSubsection := test[:length]
To avoid the error, but is there a nicer way of doing this? It feels pretty hacky to me, but then again Go generally seems to be a pretty explicit language.
答案1
得分: 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]
英文:
In Go, the answer is often to hide ugliness in a function or method. For example, a min function,
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)
}
Output:
[0 1 2 3 4]
[0 1 2 3 4]
答案2
得分: 1
如果你经常这样做,并且觉得代码很丑陋,你可以创建一个切片类型,并在其上添加一些便利方法。如果你有很多在列表上操作的便利方法(比如min、max、head、contains等),这将非常有用。我使用这种方法在字符串或整数切片上添加contains方法。
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))
}
如果你只需要这样做一次,可能不值得费力;但如果有几个循环在同一个列表上操作,那么这样做可能是值得的。当然,在这方面,如果Go语言有更复杂的通用容器会更好。
英文:
If you find yourself doing this often, and the ugliness annoys you, you can make a slice type instead and put some convenience methods on this. This is useful if you have a lot of convenience methods that operate on a list (say min, max, head, contains etc). I use this to add contains to string or int slices.
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
If you're only doing it once, it's probably not worth the effort, if you have a few loops operating on the same list, it might be. And of course this is one area where it'd be nice to have more sophisticated generic containers in Go.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论