Yes. Thanks for your help. I've been reflecting on this and I have a couple of observations:
1) In some ways, the suddenly bloated executable is useful because, as in this case, it points to a design flaw in the program.
2)
However, it was some weeks before I noticed that a problem had arisen
because I very rarely build an executable. Using "go run . " is
sufficient during the development cycle. This suggests that building and
inspecting the binary should be done periodically or possibly, for "go
run" to optionally output the resulting binary size and other
statistics.
3) I've solved the problem by
replacing the fixed sized array with a made slice. However, I can also
solve the problem by making sure I use pointer receivers in all
instances, not just those that alter the state of the type. Unless I've
missed it I don't think there is a linter for that kind of thing. It
would be very useful. I might have a crack at it myself.
What
all of this shows is that I don't have a good mental model of how the
compiler works. Naively, I thought it was "okay" but I've been surprised
by a couple of the things that I've learned. For instance, why any of
this affects the binary size. I understand why it would affect runtime
memory usage (I would have got around to optimising that once I was
confident in this part of the program's functionality) but why it
affects the binary size escapes me.
So, I have a
learning opportunity here: can anyone suggest good literature on modern
compiler design? I'd like to extend my knowledge of this subject.
Thanks again to the Go team for helping.