How can I know which interface a struct is implementing? Word

blov · · 494 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>How can I know which interface a struct is implementing? </p> <p>I can easily tell which which class is an implementation of which interface with implement keyword, but there&#39;s no such keyword in golang.</p> <hr/>**评论:**<br/><br/>RalphCorderoy: <pre><p>Go Guru. &#34;The implements query shows interfaces that are implemented by the selected type&#34; — <a href="https://docs.google.com/document/d/1_Y9xCEMj5S-7rv2ooHpZNH15JgRT5iM742gJkw5LtmQ/edit#">https://docs.google.com/document/d/1_Y9xCEMj5S-7rv2ooHpZNH15JgRT5iM742gJkw5LtmQ/edit#</a>.</p></pre>joncalhoun: <pre><p>Thanks for linking this! It is pretty awesome :D</p></pre>driusan: <pre><p>Why do you need to know which interfaces a struct is implementing?</p> <p>If you try passing it somewhere that you think it should be implementing and it&#39;s not, it&#39;ll be a compile error and you&#39;ll know right away.</p> <p>If you need to be sure it&#39;s implementing an interface, you can assign it to a variable of that type interface so that it generates a compile error. ie:</p> <pre><code>var _ io.Reader = myStruct{} </code></pre> <p>will die at compile time if myStruct ever stops implementing io.Reader.</p></pre>TheMerovius: <pre><p>If you are looking for this information, because you want to call some function which expects an interface and want to know how to get an appropriate value, <a href="https://godoc.org/golang.org/x/tools/cmd/guru">guru</a> should be able to provide you with an answer.</p></pre>r0y3: <pre><p>You can use go guru. You can watch the talk of Alan Donovan during Gophercon 2016 on youtube. Here the link <a href="http://m.youtube.com/watch?v=ak97oH0D6fI" rel="nofollow">http://m.youtube.com/watch?v=ak97oH0D6fI</a></p></pre>sethammons: <pre><p>Relevant part at about 14:30</p></pre>bear1728: <pre><p>I think you can also get this from godoc using something like: <code>godoc -http=6000 -analysis=type</code></p> <p>I don&#39;t know if that is exactly what you want, but these may be helpful:</p> <p><a href="https://github.com/golang/go/issues/2751" rel="nofollow">https://github.com/golang/go/issues/2751</a></p> <p><a href="https://golang.org/lib/godoc/analysis/help.html" rel="nofollow">https://golang.org/lib/godoc/analysis/help.html</a></p></pre>Mteigers: <pre><p>Delete a function and recompile so it no longer satisfies the interface and the compiler will let you know. </p></pre>slimsag: <pre><p>This isn&#39;t complete advice. It will only work if the struct is being used as an interface value somewhere. For example:</p> <pre><code>type Foo struct{} func (f *Foo) Error() string { ... } </code></pre> <p>Implements the builtin <code>error</code> interface, but removing the <code>Error</code> method doesn&#39;t cause the program to miscompile, <em>unless it is being used as an <code>error</code> somewhere</em>.</p></pre>PsyWolf: <pre><p>Everyone has been telling you to use go guru, and they&#39;re not wrong. That is the correct way to get this information in go. That said, you may be wondering why go doesn&#39;t have an implements keyword. Why does go need a whole separate tool like guru to give you information that java gives you right in the source code? </p> <p>Well, consider this example:</p> <pre><code>type MyStruct struct{} func (m MyStruct) Read(p []byte) (n int, err error) { return 0, nil } func (m MyStruct) Write(data []byte) (n int, err error) { return 0, nil } func (m MyStruct) Seek(offset int64, whence int) (int64, error) { return 0, nil } func (m MyStruct) Close() error { return nil } </code></pre> <p>Wanna know what that implements according to go guru?</p> <blockquote> <p>$ guru implements main.go:#70<br/> C:\Source\Go\src\github.com\psywolf\GuruTest\main.go:9:6: struct type MyStruct<br/> C:\Go\src\io\io.go:91:6: implements io.Closer<br/> C:\Go\src\io\io.go:117:6: implements io.ReadCloser<br/> C:\Go\src\io\io.go:136:6: implements io.ReadSeeker<br/> C:\Go\src\io\io.go:129:6: implements io.ReadWriteCloser<br/> C:\Go\src\io\io.go:148:6: implements io.ReadWriteSeeker<br/> C:\Go\src\io\io.go:111:6: implements io.ReadWriter<br/> C:\Go\src\io\io.go:70:6: implements io.Reader<br/> C:\Go\src\io\io.go:106:6: implements io.Seeker<br/> C:\Go\src\io\io.go:123:6: implements io.WriteCloser<br/> C:\Go\src\io\io.go:142:6: implements io.WriteSeeker<br/> C:\Go\src\io\io.go:83:6: implements io.Writer </p> </blockquote> <p>Woah! Check out how granular and still useful these interfaces can be when we aren&#39;t forced to explicitly implement them, and that&#39;s just the ones in the standard library. Anyone could create their own private &#34;SeekCloser&#34; interface, and MyStruct would work with that too! Functions that need to do IO can be very specific about which IO methods they actually need, and MyStruct will just magically work with all of them. If go forced us to explicitly implement our interfaces like java, I would have had to know about all of these in advance (which honestly, I didn&#39;t), and it would have made my type declaration stupidly verbose. </p> <p>Something like:</p> <pre><code>//not real go code type MyStruct struct implements io.Closer, io.ReadCloser, io.ReadSeeker, io.ReadWriteCloser, io.ReadWriteSeeker, io.ReadWriter, io.Reader, io.Seeker, io.WriteCloser, io.WriteSeeker, io.Writer {} </code></pre> <p>Ewww. And even then, MyStruct would never be able to work with that hypothetical private &#34;SeekCloser&#34; interface I mentioned earlier. I&#39;m really glad we don&#39;t have to do that. In practice, languages like java trend towards larger less granular interfaces so that they they don&#39;t have declarations quite this verbose, but that&#39;s a trade off we don&#39;t have to make in go.</p> <p>P.S. There are actually more important benefits when it comes to decoupling and testability, but they&#39;re more subtle so I figured I&#39;d go with this example instead. see <a href="https://golang.org/doc/faq#implements_interface" rel="nofollow">https://golang.org/doc/faq#implements_interface</a> for more details</p></pre>vassadar: <pre><p>Thank you for changing my view. I&#39;ve never considerd these benefit before.</p> <p>I just frustrated that it take somewhat blind guess when I have to learn unfamiliar library. </p></pre>drvd: <pre><p>You cannot. The interfaces a struct implements is unlimited and might grow over time and depends on which set of packages you look at.</p> <p>But you won&#39;t need this information.</p></pre>thockin: <pre><p>Won&#39;t need it? I frequently have code where I need to figure out who calls it. This is, in my opinion, one of the hardest things about Go. Code back-tracking across interfaces is nearly impossible.</p></pre>drvd: <pre><p>&#34;Who calls my code?&#34; is not &#34;What does my struct implement?&#34;. Use guru (former oracle) for that.</p></pre>SingularityNow: <pre><p>It&#39;s interesting you know about guru, but don&#39;t know it can answer the question OP is asking and think it can&#39;t be answered</p></pre>drvd: <pre><p>Not only do I know about guru, I actually use it. What it can answer is &#34;Which interfaces in my workspace does X implement?&#34;. Which ignores all interfaces out there.</p></pre>SingularityNow: <pre><p>It seems like that would have been a more useful answer than &#34;You cannot&#34;, because it&#39;s unlikely OP meant &#34;Which interfaces will my struct ever implement from now until forever&#34; and more likely they meant &#34;How can I know which interfaces my struct implements right now in the context of my work&#34;</p></pre>weberc2: <pre><p>To clarify, a Go struct (or int or string or slice or etc) implements whatever interfaces it has the methods to implement. More formally, an interface is a set of methods, and a type <em>can</em> implement an interface if the methods on the type are a superset of the methods defined by the interface.</p></pre>seriouslulz: <pre><p>On mobile right now but google &#34;go doc pointer analysis&#34;</p></pre>

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

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