Wandering Thoughts archives

2023-08-28

Go 1.22's (likely) new reflect.TypeFor() generic function

I'm always interested to see what the Go developers are doing with generic types in the standard library. One such development I've noticed recently is a new generic function in the 'reflect' package, reflect.TypeFor(); this will likely appear as part of Go 1.22. What TypeFor() does is relatively straightforward; it returns the reflect.Type of its type, which you can then use either for further reflection or to compare it to some other type (which you will likely have obtained through reflection).

The reflect package already had a reflect.TypeOf() function, but because it wasn't generic the usage was more awkward. A good example of how the change improves the readability is in net/rpc/server.go, where net/rpc needs to check to see if a method returns an error, which requires knowing the type of 'error' for reflection purposes. The old code to do this with TypeOf() was:

var typeOfError = reflect.TypeOf((*error)(nil)).Elem()

The new code using TypeFor() is simpler and more obvious:

var typeOfError = reflect.TypeFor[error]()

The old code is awkward partly because of interfaces. Because reflect.TypeOf() is passed an 'interface{}' (these days also known as 'any'), it can't directly give you the reflect.Type of an interface, because that interface type will be lost when it's converted to 'interface{}'. Instead reflect.TypeOf() returns the underlying non-interface type (or nil). As we've seen in the context of 'nil' being only sort of typed, to get around this you must pass a pointer to the interface (well, a value of the interface), get back the type 'pointer to <some interface type>', and then dereference to the original type through reflect again, which is what the original code is doing.

You might reasonably wonder how reflect.TypeFor() works, and if it has some special internal trick to access the type of interface types. The answer turns out to be no. In fact the current version in reflect/type.go is simply what the TypeOf() version was doing, generalized:

func TypeFor[T any]() Type {
  return TypeOf((*T)(nil)).Elem()
}

In Go, sometimes there is no trick, even in the reflect package.

programming/Go122ReflectTypeFor written at 22:41:16;

Link: quoting strings and breaking strings across multiple lines in YAML

This StackOverflow answer (alternate link) is an excellent, readable, all in one place answer to the twin questions of how you quote strings in YAML and how you break them across multiple lines. I learned something new about quoting strings from reading it, and I'm definitely going to want this link for future reference the next time I have something complicated to put in YAML. I'm also probably going to use '...' quoting more now that I know how simple it is to quote any stray 's I want in it.

(Via Laurence Tratt.)

links/YamlMultilineStrings written at 10:18:51;


Page tools: See As Normal.
Search:
Login: Password:

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.