登录
首页 >  Golang >  Go问答

为什么不在结构体中添加切片类型的字段?

来源:stackoverflow

时间:2024-02-15 22:06:24 211浏览 收藏

欢迎各位小伙伴来到golang学习网,相聚于此都是缘哈哈哈!今天我给大家带来《为什么不在结构体中添加切片类型的字段?》,这篇文章主要讲到等等知识,如果你对Golang相关的知识非常感兴趣或者正在自学,都可以关注我,我会持续更新相关文章!当然,有什么建议也欢迎在评论留言提出!一起学习!

问题内容

以下代码的输出让我感到惊讶:

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() 中追加(确保从追加返回的值仅分配给其第一个参数)。

我是否遗漏了一些非常明显的东西?

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

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

https://go.dev/blog/slices-intro - 同样,所有演示都使用切片文字。如果将字段移出结构,事情就会按预期工作。此行为仅在结构中发生一次。

https://yourbasic.org/golang/gotcha-append/ - 虽然它确实描述了追加无法按预期工作的行为,但解释涉及当切片有足够的容量容纳新元素时追加重用内存,从而导致意外尝试将同一数组附加到两个不同副本时的行为。就我而言,不鼓励重新分配切片操作,例如本文中的操作(some_var =append(some_other_var, elem))。

我查看了以下问题来寻求灵感:

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

初始化空切片的正确方法:解释是切片不必初始化,可以保留为 nil 并“附加到分配”,所以我相信我可以不初始化 thing.orderings。


正确答案


如果您不想使用指针,您可以为 thing 结构声明一个全局变量,并用 add 函数中的 t 值赋给它。以下是相同逻辑的代码:

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]

终于介绍完啦!小伙伴们,这篇关于《为什么不在结构体中添加切片类型的字段?》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布Golang相关知识,快来关注吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>