Any way to dynamically use packages?

blov · · 604 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I&#39;m currently writing an application that is going to support multiple different *nix distros, a few BSD machines, and possibly even Mac OS X later. At the moment I&#39;m using init() functions to dynamically build routes, but I want to make it simpler for anyone else that has to make OS additions to my code later, if possible. </p> <p>So is there a way to make a variable have all the methods of a package so I can just do varname.FunctionName() in the rest of my code?</p> <hr/>**评论:**<br/><br/>djherbis: <pre><p>What do you mean by dynamically build routes?</p> <p>The easy way to write code specific to each OS in Go is to use special filenames like: mypkg_windows.go, mypkg_linux.go. Then that file will only be included when building for that target OS. You can implement the OS specific code in each of those files, and expose the same set of functions/types/methods so that it has the same API on each platform.</p> <p>More Info: <a href="https://golang.org/pkg/go/build/">https://golang.org/pkg/go/build/</a></p> <p>One of my cross-platform packages examples: <a href="https://github.com/djherbis/times">https://github.com/djherbis/times</a></p> <p>There is not a way to call &#34;varname.FunctionName()&#34; where varname is a package. You could simulate this with a big if/switch or writing up a nice interface{} which each package has a type that meets it. But if the functionality is just platform specific, the best way is the one I mention above.</p></pre>igknighted: <pre><p>Thanks, this is useful to know for some projects I will work on later. I guess the way I&#39;m doing it is probably going to be the best solution. I&#39;m pretty much doing this: <a href="http://play.golang.org/p/mKcwrTreS7" rel="nofollow">http://play.golang.org/p/mKcwrTreS7</a></p></pre>djherbis: <pre><p>Hmm, I see. In this case it is a little trickier because it&#39;s &#34;distro&#34; specific. </p> <p>I&#39;m curious though, are things like AddSite/DeleteSite really distro specific code?</p> <p>Usually in Go we would try to isolate the variable functionality as much as possible, and use interfaces to expose the common features. </p> <p>That being said, you can always try a solution like what&#39;s done in say the zip package: <a href="https://golang.org/pkg/archive/zip/#RegisterCompressor" rel="nofollow">https://golang.org/pkg/archive/zip/#RegisterCompressor</a></p> <p>You could &#34;register&#34; a bunch of different supported distros (could be done in init()), and each distro could implement your interface.</p> <p>Then you could have a method which &#34;gets&#34; the impl. of the interface which is currently supported (by detecting the current one).</p> <p>This is a pretty dumb example, but shows off some of the idea: <a href="https://play.golang.org/p/FkuYlbdZZ5" rel="nofollow">https://play.golang.org/p/FkuYlbdZZ5</a></p> <p>I try to write my Go packages such that things like &#34;what platform/distro&#34; you are on are hidden in implementation details as much as possible. </p></pre>igknighted: <pre><p>Thanks for the example, interfaces make more sense to me now, and I&#39;ll likely re-work my application to use interfaces in a similar fashion to that. </p> <p>The API part of the application is designed to be OS specific so that if someone wants to add support for a new linux distro or different OS, they wont have to break support for another existing API. It&#39;s ultimately a controller application that configures apache, mysql, PowerDNS, postfix/dovecot, and system users. </p></pre>pierrrre: <pre><p>Use an interface.</p></pre>igknighted: <pre><p>That gets a bit messy for code organization as far as I can tell. I&#39;m currently reading through the reflect documentation, I have a feeling it might be what I need. </p> <p>Edit: <a href="/u/djherbis" rel="nofollow">/u/djherbis</a> threw a pretty simple example at me. So an interface actually is a good potential solution for what I&#39;m working on.</p></pre>szabba: <pre><p><a href="http://go-proverbs.github.io/" rel="nofollow">Reflection is never clear.</a></p></pre>igknighted: <pre><p>Haha, I like it. :)</p></pre>gchaincl: <pre><p>Build Constraints is what you&#39;re looking for: <a href="https://golang.org/pkg/go/build/" rel="nofollow">https://golang.org/pkg/go/build/</a></p></pre>igknighted: <pre><p>Negative ghost rider. This was already suggested. =/</p></pre>

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

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