How to use interfaces in Go
orel.li
orel.li
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).
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.
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.
It's 2012. Should we still be talking to computers in arcane syllables, or is there a better option?
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.
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: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...
func GetEntity(r *http.Request, v Entity) error {
Shouldn't v be a pointer here?