提问人:beep 提问时间:8/25/2023 更新时间:9/11/2023 访问量:108
在不惊慌的情况下访问 Go 切片
Accessing a Go slice without panicking
问:
当切片没有足够的元素时,如何才能在不惊慌的情况下访问切片?
我有以下代码:
str = str[:3]
但是由于它的内容长度可能会有所不同,因此当它少于 3 个元素时,它会使整个程序崩溃。有什么方法可以忽略它吗?在 Javascript 中,我可以在没有这个问题的情况下使用该方法。例如:slice
str = str.slice(0, 3);
即使长度小于 3,也会将字符串切成薄片。
答:
2赞
jub0bs
8/25/2023
#1
如果一个模拟 JavaScript 切片
方法行为的函数对你来说很方便,你可以很容易地编写一个通用的 (Go 1.21+) 函数:
package main
import "fmt"
func main() {
s := []int{1, 2, 3}
fmt.Println(Slice(s, 1, 4)) // output: [2, 3]
fmt.Println(Slice(s, 2, 1)) // output: []
fmt.Println(Slice(s, 5, 7)) // output: []
fmt.Println(Slice(s, -2, 1)) // output: [1]
}
func Slice[S ~[]T, T any](s S, lo, hi int) S {
if hi <= lo {
return nil
}
lo = clip(0, lo, cap(s))
hi = clip(0, hi, cap(s))
return s[lo:hi]
}
func clip(lo, a, hi int) int {
return max(lo, min(a, hi))
}
(操场)
如果由于某种原因,您还不能迁移到 Go 1.21+,这里有一个与 Go 1.18+ 兼容的版本:
package main
import "fmt"
func main() {
s := []int{1, 2, 3}
fmt.Println(Slice(s, 1, 4)) // output: [2, 3]
fmt.Println(Slice(s, 2, 1)) // output: []
fmt.Println(Slice(s, 5, 7)) // output: []
fmt.Println(Slice(s, -2, 1)) // output: [1]
}
func Slice[S ~[]T, T any](s S, lo, hi int) S {
if hi <= lo {
return nil
}
lo = clip(0, lo, cap(s))
hi = clip(0, hi, cap(s))
return s[lo:hi]
}
func clip(lo, a, hi int) int {
return max(lo, min(a, hi))
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
(操场)
评论
1赞
icza
8/25/2023
如果这样称呼,这会惊慌失措:SafelySlice([]int{1, 2, 3}, 2, 1)
1赞
jub0bs
8/25/2023
@icza确实如此!谢谢。固定。
评论
if cap(s) >= 3 { str = str[:3] }
len
if len(s) >= 3 { str = str[:3] }