当前位置: 首页 > 知识库问答 >
问题:

为什么结构的切片字段没有附加到?

胡昊
2023-03-14

以下代码的输出令我惊讶:

package main

import (
    "fmt"
)

type Thing struct {
  mappings  map[string]int
  orderings []string
}

func NewThing() Thing {
  t := Thing{}
  t.mappings = make(map[string]int)
  return t
}

func (t Thing) Add(s string) {
  t.mappings[s] = 1
  t.orderings = append(t.orderings, s)
}

func main() {
  t := NewThing()
  t.Add("foo")

  if len(t.mappings) == len(t.orderings) {
    fmt.Printf("Equal lengths: %v versus %v", t.mappings, t.orderings)
  } else {
    fmt.Printf("Unequal lengths: %v versus %v", t.mappings, t.orderings)
  }
}

在操场上运行时(https://play.golang.org/p/Ph67tHOt2Z_I)输出如下:

Unequal lengths: map[foo:1] versus []

我相信我对切片的处理是正确的;据我所知,它在NewThing()中被初始化为nil,并在Add()中被追加(确保从append返回的值只分配给它的第一个参数)。

我错过了一些非常明显的东西吗?

我查看了以下资源以获得解释:

https://gobyexample.com/slices-仅使用切片文字(即非结构字段)或具有设置容量的切片,我不知道t.orderings的最终大小。我的理解是append应该自动执行扩展和分配。

https://go.dev/blog/slices-intro,所有演示都使用切片文字。如果将字段移出结构,则按预期工作。这种行为在结构中只有一次发生。

https://yourbasic.org/golang/gotcha-append/-虽然它确实描述了append无法按预期工作的行为,但该解释涉及在片具有足够容量容纳新元素时追加重用内存,从而在尝试将同一数组追加到两个不同副本时导致意外行为。在我的例子中,没有像本文中那样重新分配切片操作,这是不鼓励的(some\u var=append(some\u other\u var,elem))。

我研究了以下问题以寻求灵感:

go-append to结构中的片:这个问题的解决方案是将append的结果分配回字段,我已经这样做了。

初始化空切片的正确方法:解释是切片不必初始化,可以保留为nil并“附加到分配”,所以我相信我不需要初始化这个东西。订单。

共有1个答案

欧照
2023-03-14

如果你不想使用指针,你可以声明一个全局变量的东西结构和分配它的值t从add函数。下面是相同逻辑的代码:

package main

import (
    "fmt"
)

var thing Thing

type Thing struct {
    mappings  map[string]int
    orderings []string
}

func NewThing() Thing {
    t := Thing{}
    t.mappings = make(map[string]int)
    return t
}

func (t Thing) Add(s string) {
    t.mappings[s] = 1
    t.orderings = append(t.orderings, s)

    thing = t

}

func main() {
    t := NewThing()
    t.Add("foo")

    if len(thing.mappings) == len(thing.orderings) {
        fmt.Printf("Equal lengths: %v versus %v", thing.mappings, thing.orderings)
    } else {
        fmt.Printf("Unequal lengths: %v versus %v", thing.mappings, thing.orderings)
    }
}

输出:

Equal lengths: map[foo:1] versus [foo]
 类似资料:
  • 我试图实现2个简单的结构如下: 我做错了什么?我只想在box结构上调用addItem方法并传入一个项

  • 问题内容: 我正在尝试实现2个简单的结构,如下所示: 我究竟做错了什么?我只想在框结构上调用addItem方法并在其中传递一个项目 问题答案: 嗯…这是人们在Go中附加到切片时最常犯的错误。您必须将结果分配回slice。 另外,您已经定义了类型,因此将该方法称为

  • 问题内容: 我正在努力从以下代码中获取正确的输出: 游乐场片段 打印时,结构字段为空。我敢肯定某个地方有一个愚蠢的错误,但是我仍然对Go还是陌生的,而且我已经在这里呆了几个小时。请帮忙。 问题答案: 这已经出现了很多次了。问题在于只能对导出的字段进行封送处理。 通过以大写(大写)字母开头来导出结构域。 在Go Playground上尝试一下。 请注意,JSON文本包含带有小写字母文本的字段名称,但

  • 问题内容: 我今天在go代码中遇到了奇怪的行为:当我追加到in循环中,然后尝试根据循环的结果创建new时,最后一个重写了previous 。 在这个特殊的例子这意味着 ,和切片的最后一个元素都没有,和分别,但是......始终! 第二个示例- 行为符合预期。 链接至play.golang:https : //play.golang.org/p/INADVS3Ats 经过一番阅读,挖掘和实验后,我发

  • 问题内容: 我目前正在使用GoLang创建游戏。我正在测量FPS。我注意到使用for循环将7 fps损失附加到切片上,如下所示: 我正在为每个精灵,每个平局做这些。问题是,为什么只循环几次并将相同的内容附加到这些切片中,我会得到如此巨大的性能影响?有没有更有效的方法可以做到这一点?这不像我要添加大量数据。每个切片包含大约16个元素,如上所示(4 x 4)。 当我简单地将所有16个元素合而为一时,f

  • 问题内容: 从golang规范 是否有使用内的 空白 字段的实际方案?(一些代码片段将不胜感激) 问题答案: 填充正是所谓的:一些填充,用于将以下字段与您的需求对齐,例如,匹配C结构的布局。无法访问它(至少在没有软件包不安全的情况下)。