Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
How to use interfaces in Go (orel.li)
59 points by zemo on Oct 1, 2012 | hide | past | favorite | 14 comments


I thought Go was supposed to be a clean language, but these seem pretty warty. My String[] really is substitutable for an interface{}[] within the context of a function that doesn't modify it, but there seems no way to express this. That error message when parsing a time is obscene. The way you register a JSON unmarshaller is very magic. And the subtlety about nil I see in a sibling comment seems very unfortunate. (I think I'd actually prefer sql-style "nil != nil everywhere" to "nil == nil only if they're of the same type")


My String[] really is substitutable for an interface{}[] within the context of a function that doesn't modify it, but there seems no way to express this.

Not really. The underlying representation is different, an interface is a pointer to a type and a pointer to a value. A string is a pointer to the character data and a length.

It'd get even more difficult with other data types, since an interface is two machine words, and other data types can be anything. Since a slice is backed by an array, there would be no way to do reliable indexing.

I do see your point: a slice could hold the type of its elements and then you'd have to prove that no other types are stored in the slice. But that's not really simple either.

A more consistent solution would be to store 'interface values' as pointers (rather than a pair of pointers). Then you could use a slice of pointers as a slice of interface{} (or any other interface the pointed-to type supports).


> I do see your point: a slice could hold the type of its elements and then you'd have to prove that no other types are stored in the slice. But that's not really simple either.

It's simple in typesafe languages that support generics/parametric polymorphism


It's simple in typesafe languages that support generics/parametric polymorphism

That's a different thing. The function is then instantiated to that particular type. []interface{} is more akin to an array of base class pointers. Except that in Go the type is stored with the pointer to the actual data.


Go in general seems to be a very clean language with a lot of little warts everywhere.


A strong type system gets you regularity but then you have to deal with the type system all the time (Scala). A leaner type system makes things simple, but every once in a while you have to step in and assist the type system (Go). A dynamic system can sometimes prompt you to make you own little type system. Zero sum game.

I find nothing about Go's type system quirks that would merit "warty".

The singular wart (and a tough one to remove), in my mind, is that, in general, Go's runtime makes poor use of the static aspects of the language, which is annoying given how strict the compiler appears to be at compile phase. (item: I don't mind paying the static + compile approach, but in that case, pretty please allow me to instantiate instances of types using simple string name of the type!)

I think this part of the equation needs to be tweaked, and likely will given that a combo of new library calls and a revamped runtime (you know that is the next Go story) can address this matter.


Syntactically, I find it very warty for a language that was designed and released in the last five years.

It's 2012. Should we still be talking to computers in arcane syllables, or is there a better option?


I don't mind paying the static + compile approach, but in that case, pretty please allow me to instantiate instances of types using simple string name of the type!

If go allowed that kind of "eval"-like functionality, it would be impossible to compile it down to a static binary. You would always be wondering if someone would instantiate a type that you didn't include in the binary.

Java's VM does allow creating classes from strings. It has its uses, I guess, but Go is more based around the idea of knowing the types ahead of time.

Unless you are just talking about syntax, in which case you should know that new is completely optional in most scenarios; new Foo is the same as &Foo{0}, etc.


First and foremost, thanks for this nice description of interfaces!

If you understand that an interface value is two words wide and it contains a pointer to the underlying data, that’s typically enough to avoid common pitfalls.

Except for one: namely, if a variable v that has an interface as its type and the value pointer is nil and the type pointer isn't, then v != nil. In other words, if an interface value is internally represented as:

    {*Type, *Value}
Then:

    {&DogType, nil} != nil
    {nil, nil}      == nil
This can lead to results that are initially surprising. For a description and an example:

http://golang.org/doc/go_faq.html#nil_error


Someone posted this chart[0] on the mailing list[1].

It pretty-prints a chart that shows the different nil comparisons, and what they result in (true, false, or n/a being an error caught by the compiler).

[0]: http://play.golang.org/p/7GohUdfIsD [1]: https://groups.google.com/d/topic/golang-nuts/zvqvEZk53Q0/di...


Looks like TypeScript (Microsoft's typed layer on top of JavaScript) is also using this concept of interfaces as well. Classes implicitly implement interfaces.

http://www.typescriptlang.org/Playground/#ex5


When GO introduces C like syntax and interfaces, people who hate Java and C++ (which has everything and more) jumps into the bandwagon. Interesting!


    func GetEntity(r *http.Request, v Entity) error {
Shouldn't v be a pointer here?


No but it has to be passed a pointer to a structure which implements Entity.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: