Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我应该在Go中封装切片和贴图吗?如果是,怎么做?_Go - Fatal编程技术网

我应该在Go中封装切片和贴图吗?如果是,怎么做?

我应该在Go中封装切片和贴图吗?如果是,怎么做?,go,Go,我想创建一个可以在其他包中访问的结构,但我不想允许修改此结构。在其他语言中,这是通过将所有字段设置为私有并仅公开公共getter来存档的 带getter的解决方案适用于除切片和映射之外的所有数据类型,因为返回的切片和映射在默认情况下不会被复制,所以可以修改它们。我设法找到的唯一解决方案是创建新的映射/切片,并在循环中分配所有项,但这会引入大量重复且难看的代码,特别是对于大型嵌套结构 主程序包 进口( “fmt” ) 键入OtherStruct struct{ 支柱串 } 类型结构{ 属性映射[字

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

带getter的解决方案适用于除切片和映射之外的所有数据类型,因为返回的切片和映射在默认情况下不会被复制,所以可以修改它们。我设法找到的唯一解决方案是创建新的映射/切片,并在循环中分配所有项,但这会引入大量重复且难看的代码,特别是对于大型嵌套结构

主程序包
进口(
“fmt”
)
键入OtherStruct struct{
支柱串
}
类型结构{
属性映射[字符串]其他结构
}
func(s Struct)Prop()映射[字符串]其他结构{
返回s.prop
}
func(s Struct)Prop2()映射[string]*OtherStruct{
prop:=make(映射[string]*OtherStruct,0)
对于k:=范围s.prop{
v:=s.prop[k]
道具[k]=&v
}
回程道具
}
func main(){
var-s结构;
//简易吸气剂
s=Struct{make(map[string]OtherStruct,0)}
p1:=s.Prop()
fmt.Println/&{map[]}
p1[“某物”]=OtherStruct{“测试”}
fmt.Println/{map[something:{test}]}
//复制地图的Getter
s=Struct{make(map[string]OtherStruct,0)}
p2:=s.Prop2()
fmt.Println/&{map[]}
p2[“something”]=&OtherStruct{“test”}
fmt.Println/&{map[]}
}

有没有更好的方法来封装Go中的切片/贴图?或者我根本不应该在Go中使用封装,而是使用不同的方法?

返回切片或映射值是惯用的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正在访问或可能更改切片或贴图中的元素时

让你的“getter”和“setter”在指针接收器上工作。或者更好:别担心。换成指针接收器不会改变任何事情。我担心是因为我想写好代码。对于切片(如果这就是你所说的数组),你可以使用内置的
copy
函数。对于使用For循环来创建副本的贴图,正如您已经在做的那样,这是一种可行的方法。或者,将映射/切片包装在一个结构中,该结构只为其元素提供getter,而不像您在示例中所做的那样为整个值提供getter。“因为我想编写好的代码”,您应该编写好的Go代码而不是好的Java代码。@Volker可以说,getter最好在值接收器上实现。。。也就是说:100%同意good Go code vs Java code评论:PSo也许删除所有getter并在文档中指出这些结构不应该被修改是更好的主意?我认为你是对的。在围棋中,接球手和接球手并不常见。因此,您可以去掉getter,除非您必须满足具有该数据结构的接口。IMHO,文档是可选的。