<p>I've been learning go and I absolutely love it (coming from a mostly OOP PHP background, it's definitely a breath of fresh air). So far I find interfaces to be the most confusing part. </p>
<p>Does anyone have any links to good articles explaining interfaces and how to use them effectively? Or any insight as to how they differ or compare to other code design patterns? </p>
<hr/>**评论:**<br/><br/>anoland: <pre><p>So.. interfaces aren't really any different between PHP and Go. They still define a contract. The difference is in how they are defined. Whereas, in PHP you have to explicitly state that you intend to use the interface with the <em>implements</em> keyword, in Go you don't have to do anything up front to use it.</p>
<p>This isn't an example of how interfaces work in PHP land, because the __toString() is built in and it takes care of all the magic under the covers, but it is a good example because it has a corollary between the two languages. If you have a class that has a __toString() method it has certain implicit rules about what the return value should be. Mostly that it has to contain printable characters and is usually a simple representation of the class. </p>
<p>It just so happens that Go has a <a href="http://golang.org/pkg/fmt/#Stringer">Stringer interface</a> that you would treat the same way. A simple return of printable characters, but nothing too fancy.</p>
<p>If you have a struct</p>
<pre><code>type Bucket struct {
Value int
Somestring string
}
</code></pre>
<p>and then create a String() function on that. You have just implemented the interface.</p>
<pre><code>func (b Bucket) String() string {
return b.Somestring
}
</code></pre>
<p>Try these:</p>
<p><a href="http://blog.golang.org/json-rpc-tale-of-interfaces">http://blog.golang.org/json-rpc-tale-of-interfaces</a></p>
<p><a href="http://blog.golang.org/gif-decoder-exercise-in-go-interfaces">http://blog.golang.org/gif-decoder-exercise-in-go-interfaces</a></p></pre>uabassguy: <pre><p>Very nice explanation of how it compares to PHP, definitely helps me to understand it better. I was mostly confused also by seeing empty or nil interfaces that duck typed structs and could do things in a more dynamic fashion. I do like the fact that go mostly enforces static types and it takes a lot of the guesswork out of variable typecasting (imo one of the biggest caveats of dynamic languages is needing to dump the var and pretty print it to see its structure). I wanted to see what the benefits of either side of the coin. For obvious reasons, static typing leads to less computation overhead (again one of the pitfalls of dynamic runtime compilers) and is usually less error prone at runtime. But thank you for this, as I was mostly trying to figure out how to get string values from an interface and hit a roadblock there. There's lots of good well written documentation but most often requires a lot more thought to understand first, rather than "shoot first and ask questions later"</p></pre>comrade_donkey: <pre><p><a href="http://research.swtch.com/interfaces" rel="nofollow">http://research.swtch.com/interfaces</a></p></pre>uabassguy: <pre><p>Thank you, I'll have a look</p></pre>ecmdome: <pre><p>Just making sure you have checked out Effective Go. There's a section on interfaces
<a href="https://golang.org/doc/effective_go.html#interfaces_and_types" rel="nofollow">https://golang.org/doc/effective_go.html#interfaces_and_types</a></p></pre>uabassguy: <pre><p>Thanks, yea I have been reading this one in my spare time, it is quite lengthy, but very informative </p></pre>ecmdome: <pre><p>No rush... I often go back to it and realize I'm only now understanding some of it. Its a great reference to improve yourself as an "idiomatic" gopher</p></pre>uabassguy: <pre><p>Yea I'm finding that repetition is key to understanding these things. But so far I'm really enjoying the standardized libs, after having to deal with managing application dependencies it's real nice to see the approach this language has taken. </p></pre>chreestopher2: <pre><p>Today interfaces finally "clicked" for me today... these are the droids ive been looking for.</p></pre>uabassguy: <pre><p>Definitely took some getting used to</p></pre>natefinch: <pre><p><a href="http://npf.io/2014/05/intro-to-go-interfaces/" rel="nofollow">http://npf.io/2014/05/intro-to-go-interfaces/</a></p></pre>uabassguy: <pre><p>Very well written. Thank you for sharing this</p></pre>natefinch: <pre><p>You're welcome. :)</p></pre>uabassguy: <pre><p>Think i got the basics at least now. </p>
<pre><code>package main
import "fmt"
type Animals interface{
Speak(s string)
}
type Animal struct {
Say string
}
func (a Animal) Speak() {
fmt.Printf("The %s says moo.", a.Say)
}
func main() {
a := Animal{"Cat"}
a.Speak()
}
</code></pre>
<p>Go is the cats moo</p></pre>nsd433: <pre><p>Perhaps, perhaps not. Your example code does not use the 'Animals' interface type at all. You could remove it and it would still compile and run. That is because 'a' is of type 'Animal struct', so the call to a.Speak is resolved at compile time.</p>
<p>Secondly, your Animal struct type does not implement the Animals interface because the Animals interface requires a method called Speak(string) which takes a string, while Animal.Speak() takes no arguments.</p>
<p>To make your example use an interface (not that it needs one, but just to illustrate), something like this would do:</p>
<pre><code>type Animals interface {
Speak()
}
...<Animal and Animal.Speak as you have them>...
func main() {
var i Animals
i = Animal{"Cat"}
i.Speak()
}
</code></pre></pre>uabassguy: <pre><p>Ah you are definitely right on that. I was assuming the struct would somehow inherit the interface. It does run for the intended purpose but beyond that it's not very flexible. Thank you for pointing that out! </p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传