dsh8009271 2015-07-02 14:06
浏览 44
已采纳

总是在结构域类型中使用指针的任何缺点?

Originally I figured I'd only use pointers for optional struct fields which could potentionally be nil in cases which it was initially built for.

As my code evolved I was writing different layers upon my models - for xml and json (un)marshalling. In these cases even the fields I thought would always be a requirement (Id, Name etc) actually turned out to be optional for some layers.

In the end I had put a * in front of all the fields including so int became *int, string became *string etc.

Now I'm wondering if I had been better of not generalising my code so much? I could have duplicated the code instead, which I find rather ugly - but perhaps more efficient than using pointers for all struct fields?

So my question is whether this is turning into an anti-pattern and just a bad habbit, or if this added flexibility does not come at a cost from a performance point of view?

Eg. can you come up with good arguments for sticking with option A:

type MyStruct struct {
    Id int
    Name string
    ParentId *int
    // etc.. only pointers where NULL columns in db might occur
}

over this option B:

type MyStruct struct {
    Id *int
    Name *string
    ParentId *int
    // etc... using *pointers for all fields
}

Would the best practice way of modelling your structs be from a purely database/column perspective, or eg if you had:

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
}

This example could be part of the scenario where you want to add elements from XML to the database. Here ids would generally not make sense, so instead we use nesting and references on name or other aliases. An Id for the structs would not be set until we got the id, after the INSERT query. Then using that ID we could traverse down the hierachy to the child elements etc.

This would allow us to have just 1 MyStruct, and use eg. different POST http request handler functions, depending if the call came from form input, or xml importing where a nested hierarchy and different relations might need come different handling.

In the end I guess what I'm asking is:

Would you be better off separating struct models for db, xml- and json operations (or whatever scenario that you can think of), than using struct field pointers all the way, so we can reuse the model for different, yet related stuff?

  • 写回答

1条回答 默认 最新

  • dongyaofu0599 2015-07-02 14:20
    关注

    Apart from possible performance (more pointers = more things for the GC to scan), safety (nil pointer dereference), convenience (s.a = 2 vs s.a = new(int); *s.a = 42), and memory penalties (a bool is one byte, a *bool is four to eight), there is one thing that really bothers me in the all-pointer approach. It violates the Single responsibility principle.

    Is the MyStruct you get from XML or DB same as MyStruct? What if the DB schema will change? What if the XML changes format? What if you'll also need to unmarshal it into JSON, but in a slightly different manner? And what if you need to support all that (and in multiple versions!) at the same time?

    A lot of pain comes to you when you try to make one thing do many things. Is having one do-it-all type instead of N specialised types really worth it?

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?