【问题标题】:Any down-side always using pointers for struct field types?总是使用结构字段类型的指针有什么缺点吗?
【发布时间】: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


【解决方案1】:

除了可能的性能(更多指针 = GC 要扫描的更多内容)、安全性(nil 指针取消引用)、便利性(s.a = 2 vs s.a = new(int); *s.a = 42)和内存损失(bool 是一个字节, *bool 是四到八),在全指针方法中,有一件事真正困扰着我。它违反了Single responsibility principle

您从 XML 或 DB 获得的 MyStruct 是否与 MyStruct 相同?如果数据库架构发生变化怎么办?如果 XML 改变格式怎么办?如果您还需要将其解组为 JSON,但方式略有不同,该怎么办?如果您需要同时支持所有这些(以及多个版本!)怎么办?

当你试图让一件事做很多事情时,你会遇到很多痛苦。使用一种全能类型而不是 N 种专用类型真的值得吗?

【讨论】:

  • 相当可靠的论据。我无法反驳这一点。谢谢!
猜你喜欢
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
  • 2010-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多