为了账号安全,请及时绑定邮箱和手机立即绑定

我应该在 Go 中封装 slice 和 maps 吗?如果可以,该怎么做?

我应该在 Go 中封装 slice 和 maps 吗?如果可以,该怎么做?

Go
哈士奇WWW 2023-06-19 17:10:57
我想创建一个可以在其他包中访问的结构,但我不想允许修改这个结构。在其他语言中,这是通过将所有字段设为私有并仅公开公共吸气剂来存档的。使用 getter 的解决方案适用于除切片和映射之外的所有数据类型,因为默认情况下不会复制返回的切片和映射,因此可以修改它们。我想出的唯一解决方案是创建新的地图/切片并在循环中分配所有项目,但这会引入大量重复且丑陋的代码,尤其是对于大型嵌套结构。package mainimport (    "fmt")type OtherStruct struct {    prop string}type Struct struct {    prop map[string]OtherStruct}func (s Struct) Prop() map[string]OtherStruct {    return s.prop}func (s Struct) Prop2() map[string]*OtherStruct {    prop := make(map[string]*OtherStruct, 0)    for k := range s.prop {        v := s.prop[k]        prop[k] = &v    }    return prop}func main() {    var s Struct;    // Simple getter    s = Struct{make(map[string]OtherStruct, 0)}    p1 := s.Prop()    fmt.Println(s) // &{map[]}    p1["something"] = OtherStruct{"test"}    fmt.Println(s) // {map[something:{test}]}    // Getter which copies map    s = Struct{make(map[string]OtherStruct, 0)}    p2 := s.Prop2()    fmt.Println(s) // &{map[]}    p2["something"] = &OtherStruct{"test"}    fmt.Println(s) // &{map[]}}有没有更好的方法在 Go 中封装切片/映射?或者我根本不应该在 Go 中使用封装并使用不同的方法?
查看完整描述

1 回答

?
慕田峪4524236

TA贡献1875条经验 获得超5个赞

返回切片或映射值是惯用的 Go。你的包的用户将知道这些数据结构在 Go 中是如何工作的。


在您的示例中, 的用户Struct应该知道在返回的地图中添加新条目将反映同一地图的任何其他用户。


// Simple getter

s = Struct{make(map[string]OtherStruct, 0)}

p1 := s.Prop()

fmt.Println(s) // &{map[]}

p1["something"] = OtherStruct{"test"}

fmt.Println(s) // {map[something:{test}]}

只有在并发的情况下你才应该担心这些事情。也就是说,当多个 goroutine 正在访问并可能更改切片或映射中的元素时。


查看完整回答
反对 回复 2023-06-19
  • 1 回答
  • 0 关注
  • 108 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信