提取切片的最后一个元素的Go方法是什么?

var slice []int

slice = append(slice, 2)
slice = append(slice, 7)

slice[len(slice)-1:][0] // Retrieves the last element

上面的解决方案是可行的,但看起来很尴尬。


对于只读取slice的最后一个元素:

sl[len(sl)-1]

去除方法:

sl = sl[:len(sl)-1]

请看这页关于切片技巧的文章


更尴尬的是你的程序在空切片上崩溃!

为了解决空片(零长度导致恐慌:运行时错误),您可以使用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”片可以被消除。


你可以使用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)

如果您可以使用Go 1.18或更高版本,并且经常需要访问任意元素类型的片的最后一个元素,那么使用一个小的自定义函数可以提高调用站点的可读性。另见Roger Peppe的Generics Unconstrained演讲,在那里他描述了一个类似的函数来获取片的第一个元素(如果有的话)。

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函数创建一个库;一点点复制比一点点依赖要好。