Go's reflect packages vs types package
I’m attempting to migrate some code that uses
reflect to instead use
go/types and I have some thoughts.
I’m attempting to migrate the
tool from being
reflect based to
go/types based. The main reason is so that it won’t take so long on our
repo when we do
go generate. Here are some random takeaways from this
project, so far.
First off, for my purposes
reflect has one relevant entrypoint function
TypeOf) and a single god type (
Type.) You pass the value you have to
reflect.TypeOf, get back a
reflect.Type, typically look at it’s
method, maybe the
Implements method, and then based on those you can inspect
from there. If the kind is a Map, for example, you’ll be able to look at the Key
method and the Elem method to find out the inner types.
go/types interface, interestingly, feels much more “Go” than
Instead of switching on a
Kind field and avoiding the wrong methods (because
they’ll panic) you do a type switch on the “surface” interface (
and then get a concrete type that only has the methods you can use. It’s safer
to use, but you have to know more to use it.
reflect only requires you to pass in a value to give you a
reflect.Type, to get a
types.Type you probably have to somehow parse Go.
Typically you’ll do this with
go/ast. (There’s another package that wraps both
golang.org/x/tools/go/packages, which makes
The biggest hassle for me so far (because I hadn’t fully digested what
types.Info makes available) has been naming.
reflect.Type has both Name
and PkgPath methods. This means that it’s cake to just get the name of the type
types.Type on the other hand, will only have a Name (and PkgPath) if
*types.Named; if you got one of those (and indeed even if you didn’t)
you can then access the Underlying method to get at the actual type. If you
didn’t get a
*types.Named, chances are you are just doing something wrong.
I was accessing the Types field in the Info struct and should have actually been
accessing the Defs field. There are other ways to get at this data, but
some will have names and some won’t.
Hopefully I can blog again soon about the results of this!
(The following includes affiliate links.)
If you are interested in learning Go, this is my recommendation:
If you don’t already know Go, you should definitely check out The Go Programming Language. It’s not just a great Go book but a great programming book in general with a generous dollop of concurrency.
Another book to consider learning Go with is Go Programming Blueprints. It has a nearly interactive style where you write code, see it get syntax errors (or whatever,) fix it, and iterate. A useful book that shows that you don’t have to get all of your programs perfectly working on the first compile.Posted Tue, Oct 22, 2019
If you're interested in being notified when new posts are published, you can subscribe here; you'll get an email once a week at the most.