Is there a way to eliminate hundreds of trivial interface implementations?

blov · · 430 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I have an interface, <em>Expression</em>, which has two methods: <em>Token()</em>, which returns the token the node was created from, and <em>Expr()</em>, which tells the compiler the node is an <em>Expression</em> (as opposed to a <em>Statement</em>). I then define about 15 structs which all implement this interface, which leads to me writing at least 30 entirely trivial functions with the exact same bodies (the <em>Expr()</em> methods don&#39;t even <em>have</em> bodies!)</p> <p>The implementations look like this:</p> <pre><code>// Expr tells the compiler it&#39;s an expression func (i Identifier) Expr() {} // Token returns the token func (i Identifier) Token() token.Token { return i.Tok } </code></pre> <p>(I pretty much need the comments, too, otherwise the compiler complains). This would be really easy with generics, but since they don&#39;t exist yet, is there any other good way to generate a load of trivial method implementations? I was having a look at <em>go generate</em>, but it looks a bit complicated just to shorten my code a bit.</p> <hr/>**评论:**<br/><br/>Ploobers: <pre><p>Define a common expression struct and embed it in your real structs</p> <pre><code>type exp struct{} func (e exp) Expr() {} type someExpression struct { exp Tok token.Token } </code></pre></pre>zacgarby: <pre><p>Good idea - I completely forgot about composition :)</p></pre>DeedleFake: <pre><p>This is actually what <a href="https://golang.org/src/reflect/type.go#L290" rel="nofollow">the <code>reflect</code> package</a> does for the various <code>Type</code> implementations.</p></pre>breml: <pre><p>If <code>Expr()</code> func is only used to differentiate the two interfaces and the types which implement the interface are in the same package, this method could also be defined as not exported method, which would remove the necessity of having the method documented.</p></pre>tdewolff: <pre><p>Why don&#39;t you call the function <code>Type</code> and return <code>Expr</code> which is a <code>const int</code> (from an enumeration)? You don&#39;t need any interface checks either.</p></pre>zacgarby: <pre><p>I&#39;d still need to implement Token() on each struct, and I need _Statement_s and _Expression_s to be separate types.</p></pre>DeedleFake: <pre><p>Not saying you&#39;re wrong, since I obviously haven&#39;t seen your code, but why do you <em>need</em> them to be different types? I&#39;m always wary whenever someone asks a restricted question based on the assumption that the rest of the code design that resulted in that question being necessary to ask was correct in the first place.</p></pre>zacgarby: <pre><p>It&#39;s not <em>needed</em> as such, but it helps because the compiler ensures at compile time that I only have expressions where expressions should be and the same with statements.</p></pre>breml: <pre><p>If <code>Expr()</code> func is only used to differentiate the two interfaces and the types which implement the interface are in the same package, this method could also be defined as not exported method, which would remove the necessity of having the method documented.</p></pre>

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

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