> You need to send an instance of SomeImpl to NewVar/NewFunc. Types
> aren't first-class values. To work with types you need to use the
> reflect package.
Btw, it's an interesting topic. Why they are not the first class
values. Why can't we add a syntax sugar for "reflect" package. Syntax
allows us to pass types as function arguments (it is used in functions
like 'make' and 'new'). Therefore it would be nice to have implicit
conversion from a type identifier to the reflect.Type.
Because currently the only way to get a reflect.Type is through using
an interface. But interface is a value also, of course we can make a
zero pointer value and get a type we're interested in through it, but
why can't we have a syntax sugar for that?
When we fixed up the grammar to avoid needing
a symbol table during the parse, one of my goals
was to make make and new not special, exactly
so that we could pass types to other things in
the future, like the case you've mentioned or some
unspecified form of generics.
The real question is whether the argument would
be a runtime.Type or a reflect.Type. Why are there
two at all? Because runtime.Type doesn't have
methods, which made it easier to lay down as
pre-initialized data (as opposed to initialized by code)
and also didn't require tight coupling of reflect with
the language proper.
The next time we do reflect (and I'm sure there will
be a next time) it's definitely something I'd like to
consider. We are accumulating a number of
of functions that take "zero values" as a proxy for
getting the type.
Russ
Tthe problem with this, of course, is that you can't use this
method to pass an interface type.
I'd like to see first-class types more integrated. Here's one
possibility:
- Add a new basic type to represent a runtime type, say rtype,
comparable for equality.
- Add a built in function, say typeof, which would return the rtype for
a type or an expression.
- Add a function to reflect, say NewType, to create a reflect.Type
from an rtype, and a method in reflect.Type to return its rtype.
These changes would have minimal impact on the system (nothing outside
reflect and unsafe uses runtime.Type) and I think they'd feel quite
natural.
I think it's probably worth having an explicit operator to convert
from a type expression to an rtype, to save confusion between:
x := draw.Point
and:
x := draw.Point{}
I think:
x := typeof(draw.Point)
reads just fine, and it draws the reader's attention to the fact that there's
some runtime type shenanigans going on.
I think you'll find that people disagree on exactly what OO means.
It doesn't have to mean type hierarchies and type inheritance.
Alan Kay famously once said "I invented the term Object-Oriented,
and I can tell you I did not have C++ in mind."
I doubt Go will ever have a C++/Java-style type hierarchy.
The interface idea is one of the core features of the
language. If you're not open to learning a new way to
think about programming, you're probably better off sticking
with C++ or Java or whatever you're currently using.
Russ
The documentation is usually a good place to start:
http://golang.org/pkg/reflect/
From there you might see the name Typeof and go looking for example
uses: godoc -q Typeof or type Typeof in the search box in the upper right
corner of golang.org: http://golang.org/search?q=Typeof
Also, a Google web search for [go language reflect package] turns up:
http://bitsfromthomas.blogspot.com/2010/05/go-language-reflection-examples.html
Russ
I just pass a *MyType(nil) as an interface{}, seems to work well.