如果您可以使用 Go 1.18 或更高版本,并且您经常需要访问某个任意元素类型切片的最后一个元素,则使用一个小的自定义函数可以提高调用站点的可读性:
package main
import "fmt"
func Last[E any](s []E) (E, bool) {
if len(s) == 0 {
var zero E
return zero, false
}
return s[len(s)-1], true
}
func main() {
var numbers []int
fmt.Println(Last(numbers)) // 0 false
numbers = []int{4, 8, 15, 16, 23, 42}
fmt.Println(Last(numbers)) // 42 true
}
不过,无需为该 Last
函数创建库; a little copying is better than a little dependency。
x/exp/slices
您可以使用 len(arr)
函数,尽管它会返回从 1 开始的切片长度,并且由于 Go 数组/切片从索引 0 开始,最后一个元素实际上是 len(arr)-1
例子:
arr := []int{1,2,3,4,5,6} // 6 elements, last element at index 5
fmt.Println(len(arr)) // 6
fmt.Println(len(arr)-1) // 5
fmt.Println(arr[len(arr)-1]) // 6 <- element at index 5 (last element)
更尴尬的是您的程序在空切片上崩溃!
为了应对空切片——零长度导致 panic: runtime error
,您可以使用 if/then/else 序列,或者您可以使用临时切片来解决问题。
package main
import (
"fmt"
)
func main() {
// test when slice is not empty
itemsTest1 := []string{"apple", "grape", "orange", "peach", "mango"}
tmpitems := append([]string{"none"},itemsTest1...)
lastitem := tmpitems[len(tmpitems)-1]
fmt.Printf("lastitem: %v\n", lastitem)
// test when slice is empty
itemsTest2 := []string{}
tmpitems = append([]string{"none"},itemsTest2...) // <--- put a "default" first
lastitem = tmpitems[len(tmpitems)-1]
fmt.Printf("lastitem: %v\n", lastitem)
}
这将为您提供以下输出:
lastitem: mango
lastitem: none
对于 []int
切片,您可能需要 -1
或 0
作为默认值。
从更高的层面思考,如果您的切片始终带有默认值,则可以消除“tmp”切片。
-1
索引...-1
,尽管它经常导致难以调试的错误。profiles[len(profiles)-1].UserId
的panic: runtime error: index out of range
,我猜切片的长度是 0,所以它会恐慌吗?