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

我想创建一个可以在其他包中访问的结构,但我不想允许修改这个结构。在其他语言中,这是通过将所有字段设为私有并仅公开公共吸气剂来存档的。


使用 getter 的解决方案适用于除切片和映射之外的所有数据类型,因为默认情况下不会复制返回的切片和映射,因此可以修改它们。我想出的唯一解决方案是创建新的地图/切片并在循环中分配所有项目,但这会引入大量重复且丑陋的代码,尤其是对于大型嵌套结构。


package main


import (

    "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 中使用封装并使用不同的方法?


哈士奇WWW
浏览 109回答 1
1回答

慕田峪4524236

返回切片或映射值是惯用的 Go。你的包的用户将知道这些数据结构在 Go 中是如何工作的。在您的示例中, 的用户Struct应该知道在返回的地图中添加新条目将反映同一地图的任何其他用户。// Simple getters = Struct{make(map[string]OtherStruct, 0)}p1 := s.Prop()fmt.Println(s) // &{map[]}p1["something"] = OtherStruct{"test"}fmt.Println(s) // {map[something:{test}]}只有在并发的情况下你才应该担心这些事情。也就是说,当多个 goroutine 正在访问并可能更改切片或映射中的元素时。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go