当前位置: 首页 > 面试题库 >

删除结构中切片的元素

阳光辉
2023-03-14
问题内容

我有一个结构“ Guest”,其中包含聚会客人的元数据(唯一的ID,名称,姓氏以及作为该客人的朋友的客人的唯一ID的列表。

type Guest struct {
    id      int
    name    string
    surname string
    friends []int
}

我有以下代码从朋友列表中删除ID:

func (self Guest) removeFriend(id int) {
    for i, other := range self.friends {
        if other == id {
            self.friends = append(self.friends[:i], self.friends[i+1:]...)
            break
        }
    }
}

问题是:我要删除的元素被元素的移位覆盖,但是切片不会变短。而是将切片的最后一个元素相乘。

举一个例子:guest1.friends[1,2,3,4,5]。我打电话后guest1.removeFriend(3),结果[1,2,4,5,5]却不是理想的[1,2,4,5]

那么,我在做什么错呢?


问题答案:

任何打算/确实修改接收器的方法都必须使用指针接收器。

您的Guest.removeFriend()方法确实尝试修改接收器(类型Guest),即其friends字段(属于切片类型),但是由于您仅使用了值接收器,因此您仅在修改副本的friends字段Guest。原始Guest值将具有未修改的切片值。

因此,您 必须 使用指针接收器:

func (self *Guest) removeFriend(id int) {
    // ...
}

测试它:

g := &Guest{
    id:      1,
    name:    "Bob",
    surname: "Pats",
    friends: []int{1, 2, 3, 4, 5},
}

fmt.Println(g)
g.removeFriend(3)
fmt.Println(g)

输出(在Go Playground上尝试):

&{1 Bob Pats [1 2 3 4 5]}
&{1 Bob Pats [1 2 4 5]}

关于在您的版本中看到的内容的说明,切片是指向实际包含元素的数组的小型结构描述符。在您的示例中,您修改了backing数组的元素,因此具有原始切片的调用方将看到这些修改,但是原始切片的大小不会(无法)改变。

通过使用指针接收器,您会将新的切片值(由返回append())分配给friends原始字段Guest,切片值的长度将减小1(由于删除了1个元素)。

另外请注意,在Go中使用诸如self和的接收者名称this不是惯用语,而是可以使用guestg



 类似资料:
  • 问题内容: 这个带有添加功能的删除技巧如何工作? 似乎它正在抓取第一个元素(空数组)之前的所有内容 然后将所有内容附加在第一个元素之后(位置零) …(点对点)有什么作用? 问题答案: 切片在哪里,是要删除的元素的索引: 是Go中可变参数的语法。 基本上,在 定义 函数时,它将把您传递的所有参数放入该类型的一个切片中。这样,您可以传递任意数量的参数(例如,可以传递任意数量的参数)。 现在,当 调用

  • 主要内容:从开头位置删除,从中间位置删除,从尾部删除Go语言并没有对删除切片元素提供专用的语法或者接口,需要使用切片本身的特性来删除元素,根据要删除元素的位置有三种情况,分别是从开头位置删除、从中间位置删除和从尾部删除,其中删除切片尾部的元素速度最快。 从开头位置删除 删除开头的元素可以直接移动数据指针: 也可以不移动数据指针,但是将后面的数据向开头移动,可以用 append 原地完成(所谓原地完成是指在原有的切片数据对应的内存区间内完成,不会导致

  • 我正在使用这个命令从切片中删除一个元素,但它不起作用,请建议。

  • 问题内容: 我进行了以下测试,即打印原始输入切片(过滤后),而没有删除元素,但是最后有一个额外的元素,使输入切片具有相同的长度,即使过滤后应该较短。 我已经看过这篇文档https://github.com/golang/go/wiki/SliceTricks#delete 但是我认为我缺少有关Go的一些技巧,因为似乎我使用的切片方法错误。 如何避免出现“输出片段”?(以正确的方式打印,包含正确的元

  • 我试图实现2个简单的结构如下: 我做错了什么?我只想在box结构上调用addItem方法并传入一个项

  • 问题内容: 我不理解以下代码的行为。在创建作为结构指针切片的匹配结构列表时,代码始终会打印原始数组的最后一个元素(实际上不是匹配项),它会打印12和12。但是,如果将匹配项更改为[]窗口小部件代替[] * Widget,然后将输出10和11。 为什么是这样? 问题答案: 那是因为当您使用指针时,您将添加到数组。 请注意,实际上这是循环中使用的局部变量,因此,这不是您要添加到数组中的地址。 (即使变