How to get the last element of a slice?

huangapple go评论91阅读模式
英文:

How to get the last element of a slice?

问题

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

var slice []int

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

slice[len(slice)-1:][0] // 获取最后一个元素

上述解决方案可以工作,但似乎有些笨拙。

英文:

What is the Go way for extracting the last element of a slice?

var slice []int

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

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

The solution above works, but seems awkward.

答案1

得分: 445

获取切片的最后一个元素:

sl[len(sl)-1]

删除最后一个元素:

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

参考这个切片技巧页面

英文:

For just reading the last element of a slice:

sl[len(sl)-1]

For removing it:

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

See this page about slice tricks

答案2

得分: 8

如果您可以使用Go 1.18或更高版本,并且经常需要访问某种任意元素类型的切片的最后一个元素,使用一个小的自定义函数可以提高调用点的可读性。请参阅Roger Peppe的《无约束泛型》演讲,他在演讲中描述了一个类似的函数来获取切片的第一个元素(如果有的话)。

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
}

Playground

不需要为Last函数创建一个库,一点复制比一点依赖更好

英文:

If you can use Go 1.18 or above and you often need to access the last element of a slice of some arbitrary element type, the use of a small custom function can improve readability at call sites. See also Roger Peppe's Generics Unconstrained talk, where he describes a similar function to get the first element (if any) of a slice.

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
}

(Playground)

No need to create a library for that Last function, though; a little copying is better than a little dependency.

答案3

得分: 5

你可以使用len(arr)函数来获取数组的长度,但它会返回从1开始的切片长度,而Go语言的数组/切片是从索引0开始的,所以最后一个元素实际上是len(arr)-1

示例:

arr := []int{1,2,3,4,5,6} // 6个元素,最后一个元素的索引是5
fmt.Println(len(arr)) // 6
fmt.Println(len(arr)-1) // 5
fmt.Println(arr[len(arr)-1]) // 6 <- 索引为5的元素(最后一个元素)
英文:

You can use the len(arr) function, although it will return the length of the slice starting from 1, and as Go arrays/slices start from index 0 the last element is effectively len(arr)-1

Example:

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 &lt;- element at index 5 (last element)

答案4

得分: 0

更尴尬的是,你的程序在空切片上崩溃了!为了处理空切片(长度为零导致panic: runtime error),你可以使用if/then/else序列,或者可以使用临时切片来解决这个问题。

package main

import (
	"fmt"
)

func main() {
	// 当切片不为空时进行测试
	itemsTest1 := []string{"apple", "grape", "orange", "peach", "mango"}

	tmpitems := append([]string{"none"}, itemsTest1...)
	lastitem := tmpitems[len(tmpitems)-1]
	fmt.Printf("lastitem: %v\n", lastitem)

	// 当切片为空时进行测试
	itemsTest2 := []string{}

	tmpitems = append([]string{"none"}, itemsTest2...) // <--- 在第一个位置放一个“默认”值
	lastitem = tmpitems[len(tmpitems)-1]
	fmt.Printf("lastitem: %v\n", lastitem)
}

这将给你以下输出:

lastitem: mango
lastitem: none

对于[]int切片,你可能希望将默认值设为-10

从更高的层面来思考,如果你的切片始终携带一个默认值,那么可以消除“tmp”切片。

英文:

What is even more awkward is your program crashing on empty slices!

To contend with empty slices -- zero length causing panic: runtime error, you could have an if/then/else sequence, or you can use a temporary slice to solve the problem.

package main

import (
	&quot;fmt&quot;
)

func main() {
	// test when slice is not empty
    itemsTest1 := []string{&quot;apple&quot;, &quot;grape&quot;, &quot;orange&quot;, &quot;peach&quot;, &quot;mango&quot;}

    tmpitems := append([]string{&quot;none&quot;},itemsTest1...)
    lastitem := tmpitems[len(tmpitems)-1]
    fmt.Printf(&quot;lastitem: %v\n&quot;, lastitem)

    // test when slice is empty
    itemsTest2 := []string{}

    tmpitems = append([]string{&quot;none&quot;},itemsTest2...) // &lt;--- put a &quot;default&quot; first
    lastitem = tmpitems[len(tmpitems)-1]
    fmt.Printf(&quot;lastitem: %v\n&quot;, lastitem)
}

which will give you this output:

lastitem: mango
lastitem: none

For []int slices you might want a -1 or 0 for the default value.

Thinking at a higher level, if your slice always carries a default value then the "tmp" slice can be eliminated.

huangapple
  • 本文由 发表于 2014年3月20日 22:19:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/22535775.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定