Another Go Generics Generator

xuanbao · · 1117 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I have been curious about the possibility of generating type specific, standardized algorithms using go generate and templates without the interface{} nonsense. I finally sat down and wrote some. Though far from a finished work and not very flexible (yet), it turned out to be more useful than I expected. </p> <p>I decided to slap on some lipstick (README) and a smile (LICENSE) and push it to github. If anyone finds it useful or thinks it might become useful, let me know and I will continue to update it in a more general way than my specific project requires.</p> <p><a href="https://github.com/dshills/yaggg" rel="nofollow">https://github.com/dshills/yaggg</a> - Yet Another Go Generic Generator</p> <p>If this is a new concept to anyone reading this here are some cool existing projects: <a href="http://clipperhouse.github.io/gen/" rel="nofollow">http://clipperhouse.github.io/gen/</a> <a href="https://github.com/joeshaw/gengen" rel="nofollow">https://github.com/joeshaw/gengen</a></p> <p>Enjoy...</p> <hr/>**评论:**<br/><br/>dchapes: <pre><p>IMO in the rare cases where something like this is desirable a better approach (which I got mostly completed in the past as an exercise) would be to take fully valid and compiling Go code (possibly with it&#39;s own test cases so you can test your &#34;generic&#34; implementation is correct), parse it with the existing ast package(s), change out the types, and write out the modified source to a new file.</p> <p>E.g. Take <code>set_stub.go</code> something like (a silly example with a trivial set implementation):</p> <pre><code> // +build ignore package foo type T int // Placeholder // T_Set is a set of T type T_Set map[T]struct{} func New_T_Set(n int) { return make(T_Set, n) } // Add adds i to the T_Set. func (s T_Set) Add(i T) { s[i] = struct{}{} } // Remove removes i from the T_Set. func (s T_Set) Remove(i T) { delete(s, i) } // Has returns true if i is in the T_Set. func (s T_Set) Has(i T) bool { var x T // note, useless extra variable just for show x = T(i) _, ok := s[x] return ok } </code></pre> <p>And with a gogenerate line containing something like <code>T=int</code> produce a file something like this:</p> <pre><code> package foo // IntSet is a set of int type IntSet map[int]struct{} func NewIntSet(n int) { return make(IntSet, n) } // Add adds i to the IntSet. func (s IntSet) Add(i int) { s[i] = struct{}{} } // Remove removes i from the IntSet. func (s IntSet) Remove(i int) { delete(s, i) } // Has returns true if i is in the IntSet. func (s IntSet) Has(i int) bool { var x int x = int(i) _, ok := s[x] return ok } </code></pre> <p>(note the extra variable in <code>Has</code> is just to show template re-writing)</p></pre>dshills: <pre><p>Interesting. So you see the advantage of doing it this way is to insure compilable code and an easy way to test? I could certainly see that. I actually use the _test.go to run a full version and then copy it to the templates which seemed a little backwards :P</p> <p>As I mention in the post I did it as much for a proof of concept as anything else. </p> <p>Outside of a change in the language spec I would love if someone standardized something like this. It would be great to have a large library of algorithms available written by people smarter than me to drop into projects. Something like STL</p></pre>dchapes: <pre><p>I too wrote the tool that does (most of) what I gave just as a proof of concept (and to play with the ast package).</p> <p>In practice I&#39;ve never really needed anything like this (e.g. I call the set example I used &#34;silly&#34; since in practice when I need such a set I just write out the couple of lines it takes and often use a map of bools directly without methods. Just as whenever I need sorting I just write out the trivial one-liner <code>Len</code> and <code>Swap</code> methods in-front of the sometimes more involved <code>Less</code> method that are needed for <code>Sort.Interface</code>).</p></pre>dshills: <pre><p>I guess that is the argument from the Go team. You don&#39;t need that stuff very often and when you do it isn&#39;t hard to write. I&#39;m not completely sold but I&#39;m about to embark on my first large scale Go project so we shall see :)</p></pre>icholy: <pre><p>Heh, I arrived at the exact same idea of using <code>_T_</code> in the method/function/type names to be replaced while implementing (never finished it) my own go generics implementation.</p></pre>dchapes: <pre><p>Mine uses whatever string is provided (e.g. &#34;K=string V=int&#34; or &#34;T1=MyType T2=OtherType&#34;, etc) and replaces <code>T</code>, <code>Foo_T</code>, <code>T_Foo</code>, or <code>Foo_T_Bar</code> (Under the assumption that idiomatic Go code otherwise avoids &#34;_&#34; in identifiers). For types like &#34;int&#34; it capitalizes as appropriate (or an alternate can be specified). The annoying thing that I never bothered getting fully correct was editing the comments.</p></pre>anlhord: <pre><p>and the advantage on simply using copy+paste &amp; search+replace?</p></pre>dshills: <pre><p>None other than simplicity and repeatability. copy+paste with search and replace was how I was doing it before I wrote this :)</p> <p>Also was curious if it was doable. </p> <p>oh I so wish we had generics :( I love working in Go. It is the only thing in the entire workflow that really frustrates me.</p></pre>anlhord: <pre><p>as a person implementing generics to gccgo (against the will of go authors), I can guarantee you will keep frustrated, even if they are implemented.</p> <p>most blatant copy paste cases will be reduced, but there will be still rough edges. things like operator overloading etc... </p> <p>furthermore for example when u subtract *T - *T and provide T type as struct or whatever what should happen. etc..</p></pre>

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

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