

How to use interfaces in Go - zemo
http://orel.li/SxBSxe

======
danieldk
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>

~~~
drbawb
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...](https://groups.google.com/d/topic/golang-
nuts/zvqvEZk53Q0/discussion)

------
lmm
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")

~~~
danieldk
_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).

~~~
djhworld
> _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

~~~
danieldk
_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.

------
thebigshane
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>

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

------
a1k0n

        func GetEntity(r *http.Request, v Entity) error {
    

Shouldn't v be a pointer here?

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

