Understanding interfaces

agolangf · 2015-06-23 06:22:06 · 986 次点击    
这是一个分享于 2015-06-23 06:22:06 的资源,其中的信息可能已经有所发展或是发生改变。

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.

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?


评论:

anoland:

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 implements keyword, in Go you don't have to do anything up front to use it.

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.

It just so happens that Go has a Stringer interface that you would treat the same way. A simple return of printable characters, but nothing too fancy.

If you have a struct

type Bucket struct {
    Value int
    Somestring string
}

and then create a String() function on that. You have just implemented the interface.

func (b Bucket) String() string {
    return b.Somestring
}

Try these:

http://blog.golang.org/json-rpc-tale-of-interfaces

http://blog.golang.org/gif-decoder-exercise-in-go-interfaces

uabassguy:

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"

comrade_donkey:

http://research.swtch.com/interfaces

uabassguy:

Thank you, I'll have a look

ecmdome:

Just making sure you have checked out Effective Go. There's a section on interfaces https://golang.org/doc/effective_go.html#interfaces_and_types

uabassguy:

Thanks, yea I have been reading this one in my spare time, it is quite lengthy, but very informative

ecmdome:

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

uabassguy:

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.

chreestopher2:

Today interfaces finally "clicked" for me today... these are the droids ive been looking for.

uabassguy:

Definitely took some getting used to

natefinch:

http://npf.io/2014/05/intro-to-go-interfaces/

uabassguy:

Very well written. Thank you for sharing this

natefinch:

You're welcome. :)

uabassguy:

Think i got the basics at least now.

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()
}

Go is the cats moo

nsd433:

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.

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.

To make your example use an interface (not that it needs one, but just to illustrate), something like this would do:

type Animals interface {
  Speak()
}
...<Animal and Animal.Speak as you have them>...
func main() {
   var i Animals
   i = Animal{"Cat"}
   i.Speak()
}
uabassguy:

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!


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

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