Objectified
Last time I wrote a simple program using Go to convert Intel-style hex files to binary. I deliberately set out to write that version to mimic the style you might use in a normal C program. However, Go has features that allow modern object-oriented techniques. If you are a C++ programmer, some of Go's features will seem a bit strange, although if you are a Java programmer, it might be a little more familiar (although still not quite the same).
To explore Go's features, I rewrote the hex file converter to use what passes for Go objects. It really isn't such a big change, but it shows a good contrast between the C-style of coding and a more authentic Go experience.
If you are used to C++, you might be surprised to find that Go doesn't have inheritance. When I used to teach programming classes, I would often ask students what three things do we expect from object-oriented programming? My answers are: encapsulation, reuse, and polymorphism. Invariably, a student would ask: "What about inheritance?" Inheritance isn't a goal. It is a way many common languages get reuse and polymorphism. That is, if class B derives from class A you can assume that the code in class A is largely reused in B. You can also treat pointers to instances of B as though they were pointers to instances of A (thus, polymorphism).
That's one way to do it. ActiveX, for example, doesn't really support inheritance either, but it does support all three goals. Java supports inheritance but also provides interfaces to allow polymorphism without hierarchical limitations.
That's Go's model. Interfaces are just collections of method signatures and any type that supports those methods implements that interface even if the programmer who wrote the type didn't know about the interface at the time. This is somewhat simplified because Go types don't directly declare their methods anyway.
That's probably easier to explain with an example. The entire source code for hex2bin1.go is online. However, here's the type I used to model each line from the hex file. This is the closest thing Go has to an object in the C++ or Java sense:
type HexLine struct {
isEOF bool
len byte
addr int16
csum byte
data []byte
}
This looks a lot like a C structure (except Go has the types after the field names instead of before). What's missing is the methods and visibility markers like public, private, and protected.
My "object" actually does have two methods: print and procline. Here's the print method:
func (l HexLine) print(text bool) {
// do output
if text {
for i:=byte(0);i<l.len;i++ {
fmt.Fprintln(w, l.data[i])
}
} else {
w.Write(l.data)
}
}
The key is the first line:
func (l HexLine) print(text bool) {
You might read this as "a function that applies to an instance of HexLine that we will call l, named print, that takes a single Boolean argument and returns nothing. The l parameter is like the this parameter in C++; it will refer to the "current" object.
The main part of the program that uses this "object" looks like this:
var line HexLine;
line.procline(string(buf))
if !line.isEOF {
line.print(ltext)
The calls line.procline and line.print are what execute the methods.
The print method takes an actual instance of the type as a target and that's not a problem because it doesn't modify the data in the structure. However, the procline method does. That means it needs to target a pointer to the structure.
Keep in mind that with Go, the compiler figures out if you are accessing a full type or a pointer, so line.procline automatically uses a pointer (there is no need for the -> syntax in Go). Similarly, inside either method, you don't say l->isEOF, you simply use l.isEOF.
Although I don't think Go is quite ready for hardcore bare metal programming, I'd consider using it for some of the work I do on small Linux boards. I haven't done much with it and GUIs, but the GUI library bindings don't seem to be very mature so I'll probably stick to Qt for any GUI work. Then again, Go is billed as a systems programming language and many of the programs you'd consider in that genre work fine without a GUI.

