您好,欢迎访问一九零五行业门户网

go语言中list怎么删除元素

在go语言中,可以使用remove()函数来删除list元素,语法“list对象.remove(element)”,参数element表示要删除列表元素。element元素不能为空,如果不为空则返回被删除的元素的值,如果为空则会报异常。
本教程操作环境:windows7系统、go 1.18版本、dell g3电脑。
go提供了一个list包,类似python的list,可以存储任意类型的数据,并提供了相应的api,如下:
type element func (e *element) next() *element func (e *element) prev() *elementtype list func new() *list func (l *list) back() *element func (l *list) front() *element func (l *list) init() *list func (l *list) insertafter(v interface{}, mark *element) *element func (l *list) insertbefore(v interface{}, mark *element) *element func (l *list) len() int func (l *list) moveafter(e, mark *element) func (l *list) movebefore(e, mark *element) func (l *list) movetoback(e *element) func (l *list) movetofront(e *element) func (l *list) pushback(v interface{}) *element func (l *list) pushbacklist(other *list) func (l *list) pushfront(v interface{}) *element func (l *list) pushfrontlist(other *list) func (l *list) remove(e *element) interface{}
其中,remove()函数用于列表list删除元素,删除的元素不能为空,如果为空,会报异常。
remove(e *element) interface{}
参数描述
e 要删除列表元素。
返回值
返回被删除的元素的值。
列表删除元素的示例
示例1:
package mainimport ( "container/list" "fmt")func main() { //使用 remove 在列表中删除元素 listhaicoder := list.new() listhaicoder.pushfront("hello") listhaicoder.pushfront("haicoder") element := listhaicoder.pushfront("hello") removeele := listhaicoder.remove(element) fmt.println("removeelement =", removeele) for i := listhaicoder.front(); i != nil; i = i.next() { fmt.println("element =", i.value) }}
分析:
我们通过 list.new 创建了一个列表 listhaicoder,接着使用 pushfront 函数在列表中插入三个元素,接着使用 remove 函数删除了最后插入的元素。
最后,我们打印被删除的元素和删除后的列表,remove 函数返回的是被删除的元素的值,同时,我们发现最后插入的元素已经被成功从列表删除了。
示例2:删除空元素
package mainimport ( "container/list" "fmt")func main() { //使用 remove 在列表中删除空元素,报错 listhaicoder := list.new() listhaicoder.pushfront("hello") listhaicoder.pushfront("haicoder") listhaicoder.remove(nil)}
程序运行后,控制台输出如下:
扩展知识:list删除所有元素
借助list包提供的api,list用起来确实挺方便,但是在使用过程中,如果不注意就会遇到一些难以发现的坑,导致程序结果不是预想的那样。这里要说的坑是通过for循环遍历list,并删除所有元素时会遇到的问题。例如,下面这个示例程序创建了一个list,并依次将0-3存入,然后通过for循环遍历list删除所有元素:
package mainimport ( "container/list" "fmt")func main() { l := list.new() l.pushback(0) l.pushback(1) l.pushback(2) l.pushback(3) fmt.println("original list:") prtlist(l) fmt.println("deleted list:") for e := l.front(); e != nil; e = e.next() { l.remove(e) } prtlist(l)}func prtlist(l *list.list) { for e := l.front(); e != nil; e = e.next() { fmt.printf("%v ", e.value) } fmt.printf("n")}
运行程序输出如下:
original list:0 1 2 3deleted list:1 2 3
从输出可以知道,list中的元素并没有被完全删除,仅删除了第一个元素0,和最初设想不一样,按照go的使用习惯,遍历一个list并删除所有元素写法应该如下:
for e := l.front(); e != nil; e = e.next() { l.remove(e)}
但是根据上面示例代码的输出,这样删除list所有元素是无效的,那么问题出在哪呢?由for循环的机制可以知道,既然删除了第一个元素,没有删除第二个元素,肯定是第二次循环的条件无效,才导致循环退出,即执行完下面语句后:
l.remove(e)
e应该为nil,所以循环退出。在for循环中的l.remove(e)语句前添加打印语句验证,例如添加如下语句:
fmt.println("delete a element from list")
运行程序输出如下:
original list:0 1 2 3deleted list:delete a element from list1 2 3
可以看到,确实只循环了一次,循环就结束了。即当执行完语句l.remove(e)后,e等于e.next(),因为e.next()为nil,导致e为nil,循环退出。为什么e.next()会是nil呢?通过查看go list源码,如下所示:
// remove removes e from its list, decrements l.len, and returns e.func (l *list) remove(e *element) *element { e.prev.next = e.next e.next.prev = e.prev e.next = nil // avoid memory leaks e.prev = nil // avoid memory leaks e.list = nil l.len-- return e}// remove removes e from l if e is an element of list l.// it returns the element value e.value.func (l *list) remove(e *element) interface{} { if e.list == l { // if e.list == l, l must have been initialized when e was inserted // in l or l == nil (e is a zero element) and l.remove will crash l.remove(e) } return e.value}
由源码中可以看到,当执行l.remove(e)时,会在内部调用l.remove(e)方法删除元素e,为了避免内存泄漏,会将e.next和e.prev赋值为nil,这就是问题根源。
修正程序如下:
package mainimport ( "container/list" "fmt")func main() { l := list.new() l.pushback(0) l.pushback(1) l.pushback(2) l.pushback(3) fmt.println("original list:") prtlist(l) fmt.println("deleted list:") var next *list.element for e := l.front(); e != nil; e = next { next = e.next() l.remove(e) } prtlist(l)}func prtlist(l *list.list) { for e := l.front(); e != nil; e = e.next() { fmt.printf("%v ", e.value) } fmt.printf("n")}
运行程序输出如下:
original list:0 1 2 3deleted list:
可以看见,list中的所有元素已经被正确删除。
【相关推荐:go视频教程、编程教学】
以上就是go语言中list怎么删除元素的详细内容。
其它类似信息

推荐信息