Exported / Unexported best practices?

blov · · 1904 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>The Go documentation explains the difference between exported/unexported functions/methods/fields, but is a little light on recommendations for when to use each.</p> <p>Is it right to think of exported methods/functions as the API of your package and unexported methods/functions as basically private helper methods?</p> <p>Also, with fields is it right to assume that unexported structs should have unexported fields and exported structs should have exported fields? Are there any other considerations to take into account?</p> <p>And is there any performance difference between unexported vs. exported? Is there any downside to exporting everything by default?</p> <p>Thanks!</p> <hr/>**评论:**<br/><br/>BESSEL_DYSFUNCTION: <pre><p>I think it&#39;s always correct to treat the exported functions as your API. I could imagine cases where someone might export fields that they don&#39;t want the user shouldn&#39;t touch for marshaling purposes, but doing something like that makes me squeamish.</p> <p>Public structs can have as many or as few public fields as you want, just like in any other language. In general, private structs should have private fields unless you have a specific reason to do otherwise. Public fields in private structs can be used outside of the package if they&#39;re embedded in public structs. Suppose you have this code in some package called <code>pkg</code>:</p> <pre><code>type private struct { A int } type Public struct { private B int } </code></pre> <p>In some importing package, the following code will work just fine:</p> <pre><code>p := new(pkg.Public) println(p.A, p.B) </code></pre> <p>This is something that you might do in some cases where you have some common set of methods and fields shared by a bunch of exported structs, but I&#39;d generally avoid it because I don&#39;t think it plays nicely with <code>godoc</code>.</p> <p>There&#39;s no performance difference between exported and unexported fields/methods/etc.</p></pre>elithrar_: <pre><blockquote> <p>In general, private structs should have private fields unless you have a specific reason to do otherwise. </p> </blockquote> <p>To add: the most common reason being encoding those fields into gob/JSON/etc, where your private type is an &#34;implementation detail&#34; that the user doesn&#39;t need to touch.</p> <p>But: definitely don&#39;t export everything by default. In fact, I&#39;d argue the opposite: export only the bare minimum required, and think hard about anything else you export beyond that. Every exported symbol is weight added to your API, and risk of API breakage if you have to change it.</p></pre>jerf: <pre><blockquote> <p>In fact, I&#39;d argue the opposite: export only the bare minimum required, and think hard about anything else you export beyond that. Every exported symbol is weight added to your API, and risk of API breakage if you have to change it.</p> </blockquote> <p>Since in Go we are generally distributing everything as source, rather than &#34;public&#34; and &#34;private&#34;, I tend to think of it as &#34;public&#34; and &#34;fork it to make it public&#34;, rather than private&#39;s implication of &#34;nothing you can do will make this available to you&#34;. Consequently, I think it&#39;s very safe to default to a rather minimum, &#34;make easy things easy&#34; clean API, maybe with some intermediate stuff in there if appropriate, but you don&#39;t have to write your API for the rare mega-expert who needs deep, deep access into everything... let them maintain their own fork, they&#39;re probably going to be screwing around with it anyhow. That is, you don&#39;t have to worry about that use case when creating your public Go API, so, well, don&#39;t. Keep it simple or at most intermediate and let the experts joust with the source themselves.</p></pre>elithrar_: <pre><blockquote> <p>I think it&#39;s very safe to default to a rather minimum, &#34;make easy things easy&#34; clean API, maybe with some intermediate stuff in there if appropriate, but you don&#39;t have to write your API for the rare mega-expert who needs deep, deep access into everything</p> </blockquote> <p>Couldn&#39;t agree more. Part of the design process is knowing what kind of &#39;demographic&#39; might use your library, and what it does.</p> <p>Designing a crypto-related library for REST API users? Minimise the sharp edges and keep to a minimal API surface. Writing an SQL driver? You might want to expose more to allow flexibility for downstream packages to leverage, etc.</p></pre>

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

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