【发布时间】:2015-07-02 14:06:26
【问题描述】:
最初我认为我只会将指针用于可选结构字段,在最初构建它的情况下,这些字段可能会为 nil。
随着代码的发展,我在模型上编写了不同的层 - 用于 xml 和 json (un) marshalling。在这些情况下,即使是我认为始终是要求的字段(Id、Name 等)实际上对于某些层来说都是可选的。
最后我在所有字段前面都放了一个 *,包括 int 变成 *int,string 变成 *string 等等。
现在我想知道我是否最好不要如此概括我的代码?我本可以复制代码,但我觉得这很丑陋 - 但可能比对所有结构字段使用指针更有效?
所以我的问题是,这是否会变成一种反模式并且只是一个坏习惯,或者从性能的角度来看,这种增加的灵活性不会以成本为代价?
例如。你能提出坚持选项 A 的好论据吗:
type MyStruct struct {
Id int
Name string
ParentId *int
// etc.. only pointers where NULL columns in db might occur
}
在这个选项 B 上:
type MyStruct struct {
Id *int
Name *string
ParentId *int
// etc... using *pointers for all fields
}
对你的结构建模的最佳实践方法是从纯粹的数据库/列的角度来看,或者如果你有:
func (m *MyStruct) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var v struct {
XMLName xml.Name `xml:"myStruct"`
Name string `xml:"name"`
Parent string `xml:"parent"`
Children []*MyStruct `xml:"children,omitempty"`
}
err := d.DecodeElement(&v, &start)
if err != nil {
return err
}
m.Id = nil // adding to db from xml, there's initially no Id, until after the insert
m.Name = v.Name // a parent might be referenced by name or alias
m.ParentId = nil // not by parentId, since it's not created yet, but maybe by nesting elements like you see above in the V struct (Children []*ContentType)
// etc..
return nil
}
此示例可能是您希望将 XML 中的元素添加到数据库的场景的一部分。这里 ids 通常没有意义,所以我们使用嵌套和引用 name 或其他别名。直到我们在 INSERT 查询之后获得 id 后,才会设置结构的 Id。然后使用该 ID,我们可以将层次结构向下遍历到子元素等。
这将允许我们只有 1 个 MyStruct,并使用例如。不同的 POST http 请求处理函数,取决于调用是来自表单输入,还是来自嵌套层次结构和不同关系可能需要不同处理的 xml 导入。
最后我猜我要问的是:
将 db、xml 和 json 操作(或任何您能想到的场景)的结构模型分开,而不是一直使用结构字段指针,这样我们可以将模型重用于不同但相关的模型,这样会更好吗?东西?
【问题讨论】:
-
如果它是原语并且不可为空,您为什么还要考虑使用指针?这样做只会使您的内存消耗翻倍,并增加维护代码的人员的认知开销。
标签: go