Style question about database create functions

blov · · 419 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>An bad title I know, basically it comes down to these two different situations.</p> <p>First if we have a create method which accepts a pointer to the model:</p> <pre><code>func Create(model *Model) error { model, err := db.Insert(model) if err != nil { return err } return nil } </code></pre> <p>Second we have a method which also returns the pointer</p> <pre><code>func Create(model *Model) (*Model, error) { model, err := db.Insert(model) if err != nil { return nil, err } return model, nil } </code></pre> <p>I was erring towards the second signature because it lets you use a literal as the argument to create and still have a reference at the end of the method.</p> <p>Views?</p> <hr/>**评论:**<br/><br/>tmornini: <pre><p>Why not:</p> <p>func (model *Model) Create() error</p></pre>ROFLLOLSTER: <pre><p>Because then you can&#39;t do:</p> <pre><code>model, err := Create(&amp;Model{fields...}) </code></pre></pre>tmornini: <pre><p>Fair enough</p> <pre><code>func (model *Model) Create() (*Model, error) </code></pre> <p>Allows</p> <pre><code>model, err := &amp;Model{fields ...}.Create() </code></pre></pre>shovelpost: <pre><p>I don&#39;t think it is is a good idea to add database logic to your application&#39;s structs.</p></pre>tmornini: <pre><p>I would have agreed with that in the past.</p> <p>Now that I&#39;m thinking purely in terms of HTTP microservice systems, I find there&#39;s no benefit in the additional complexity.</p> <p>OP code implied the Create func was already in the Model struct&#39;s package.</p> <p>EDIT: 180 degree turn around after thinking it through.</p></pre>ROFLLOLSTER: <pre><p>They are actually in different packages, just wrote it that way for brevity because I&#39;m on mobile.</p></pre>tmornini: <pre><p>All good!</p></pre>shovelpost: <pre><p>I believe there is a 3rd option:</p> <pre><code>func Create(u User) (User, error) or func Create(u User) (*User, error) </code></pre> <p>You pass a copy with only the required values filled like say <code>Name</code> and you return a brand new user that contains the rest like <code>ID</code> and <code>Created</code>.</p> <p>I think it makes a little more sense than:</p> <pre><code>func Create(u *User) (*User, error) </code></pre> <p>Because if we are passing a pointer then why return it? Is it the same one? If it is then why not modify the original one instead? Of course there is still the argument that <code>User</code> might be big and we do not wish to copy it. So...</p> <p>I think my favorite option is :</p> <pre><code>func Create(u *User) error </code></pre> <p>Where you pass a pointer and after the function ends successfully if we inspect the fields of <code>u</code> the fields like <code>ID</code> and <code>Created</code> have been filled with the values from the database. It feels a little more &#34;lightweight&#34; to me and the fact that you pass down a pointer it means that the function is planning to modify its values.</p> <p>In the end I don&#39;t think it matters too much. Just be consistent across the codebase.</p> <p>P.S. I know it was an example but I detest seeing things like <code>models.Model</code> with <code>models</code> being the worst part.</p></pre>dasopranos: <pre><p>I like the second one. It makes the code smaller which is always good, and IMHO it makes it more readable too.</p> <p>Infact I go even futher, i would do: <a href="https://play.golang.org/p/6e_Er9PtdH" rel="nofollow">https://play.golang.org/p/6e_Er9PtdH</a></p> <p>(sorry i couldnt get reddit code formatting to work)</p></pre>tmornini: <pre><p>You&#39;re headed down the road to creating your own ORM.</p> <p>The path to hell is paved with good intentions!</p></pre>dasopranos: <pre><p>I don&#39;t see it. What I see is the orthognality of the DB and Model concepts in my program.</p> <p>&#34;Simplicity comes from orthogonality and predictability.&#34; -- Rob Pike</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

419 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传