Question about interfaces

agolangf · · 381 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Hey guys<br/> coming from a java world I try to grasp the concepts of go&#39;s interfaces. As far as I understood, the interfaces are implemented implicitly if all methods are satisfied. But isn&#39;t one of the ideas behind interfaces to force the implementation? Like when I have a huge&#39;ish interface and I miss to implement a method, the compiler just won&#39;t assign the interface to it. Can I enforce that the compiler checks that? </p> <p>Also, in Java I can easily see what interfaces are implemented by a class. Seeing a runnable allows me to see that I can run this in a thread. But in go, I have no clue what interfaces are implemented as I have to check the implementations if they match any interface. Is there a way to identify the implemented interfaces?</p> <p>Thanks</p> <hr/>**评论:**<br/><br/>joncalhoun: <pre><p>Interfaces are used differently in Go than in Java so it may feel weird at first but it is insanely useful to have things implement an interface without explicitly stating that they do. </p> <p>That said, if you want to double check that a type you are creating implements an interface you can do something like below in the source where you declare the type.</p> <p><code>var _ MyInterface = MyType{}</code></p> <p>If <code>MyType</code> doesn&#39;t implement <code>MyInterface</code> then the compiler will complain and it is somewhat equivalent to what you would see in Java.</p></pre>cristiandeives: <pre><p>If your code uses that type (which implements the interface) in some place where the interface type is required, the compiler <em>will</em> check if your type implements it. So if you miss to implement a method (or let&#39;s say a new method is added to the interface later), the code won&#39;t compile anymore.</p> <p>The tool &#39;guru&#39; (golang.org/x/tools/cmd/guru) can print the interfaces that a certain type implements. For example:</p> <p>$ guru implements file.go:#offset</p> <p>It&#39;s not very practical to use this tool in the command line because you need to specify the byte offset of the type declaration, but that tool was specifically made to be used by other tools, like editors, IDEs, etc. Find out how to use guru in your editor then it becomes very easy :)</p></pre>ArghusSquare: <pre><p>Alright thanks, even though needing an external tool makes it a bit harder to grasp it on e.g. github, but that&#39;s how the language works I guess :)</p> <p>thanks</p></pre>LimEJET: <pre><p>It&#39;s not really needed. The compiler catches it.</p> <p>If you try to pass something that&#39;s <em>supposed</em> to implement an interface, but doesn&#39;t, to something that <em>expects</em> that interface, the program will not compile.</p></pre>itsamemmario: <pre><p>In go the compiler checks if sometihng implements an interface too. If you create a slice of io.wirter and you try to add your homemade struct to it. It will tell you to implement the write method just like java. The the fact that you don&#39;t have to declare anywhere who implements which interface means that you can use someone else his code much more easily. In the standard library there a great examples of this. The reader and writer interfaces are used everywhere. A nice article on how you use interfaces in go compared to in java can be found here: <a href="https://medium.com/@cep21/preemptive-interface-anti-pattern-in-go-54c18ac0668a#.dqp65ah91" rel="nofollow">https://medium.com/@cep21/preemptive-interface-anti-pattern-in-go-54c18ac0668a#.dqp65ah91</a> </p></pre>ArghusSquare: <pre><p>I don&#39;t seem to get the article.<br/> It speaks about Java needing to define and implement an Interface for the takeAction method in the logic class, but in Go you also need an interface and you need to implement the methods. The only thing that&#39;s missing is the &#34;implements&#34; keyword. (Assuming you weren&#39;t lucky enough to already have a function with the same name in your struct)</p> <p>And would the compiler know what interface I want to implement?</p> <p>Seems like I&#39;m to java&#39;ish or too dumb :/</p></pre>Sythe2o0: <pre><p>The compiler knows what you want to implement in the sense that anything you satisfy the requirements for, you already do implement. </p></pre>ArghusSquare: <pre><p>But let&#39;s say I have an interface Runnable with a run method. So every single struct with a run method actually implicitly implements the Runnable interface right? What if someone intended the run method for something else (like a Person walking 5 miles). In the code it would actually think, hey the run method works, you can pass the object here without any problem. Or do I overlook something?</p></pre>Sythe2o0: <pre><p>That Run Method would need to have the same arguments and return values, but if it did it would work that way. That&#39;s an issue on the last user&#39;s part for misusing a library, as we often want exactly this functionality.</p></pre>lattakia: <pre><p>Read up on <em>Duck Typing</em>.</p> <p>The method signatures in the interface &amp; implementing structs must match exactly. There&#39;s no covariant return types for method sigs like in Java. </p></pre>djherbis: <pre><p>Usually you should comment on an &#39;impl&#39; method what interface it&#39;s implementing (unless it&#39;s obvious like Read/Write) so that users know that it provides the expected behavior for that interface. </p> <p>Here&#39;s an <a href="https://golang.org/pkg/go/scanner/#ErrorList.Error" rel="nofollow">example</a> from the std lib. Usually it&#39;s of the form: &#34;StructName implements the InterfaceName interface.&#34;</p> <p>There&#39;s also <em>marker methods</em> which do nothing but can be added to an interface to help differentiate it from other interfaces which would otherwise have the same method sets, <a href="https://golang.org/pkg/os/#Signal" rel="nofollow">os.Signal</a> for example.</p></pre>ChristophBerger: <pre><p>In addition to what has been said already in the other answers:</p> <blockquote> <p>Like when I have a huge&#39;ish interface</p> </blockquote> <p>Then you have a Java interface. In Go, interfaces are kept small. Interfaces with only one or two methods are common. Read e.g. the section &#34;Liskov Substitution Principle&#34; in [SOLID Go Design](Liskov Substitution Principle) about the intention behind Go-style interfaces. (<em>Effective Go</em> also <a href="https://golang.org/doc/effective_go.html#interfaces" rel="nofollow">promotes small interfaces</a> but without further explanation.)</p></pre>

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

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