Structs, Methods & Embedding
Structs, value vs pointer receivers, constructor functions, and composition by embedding.
Go has no classes. Data lives in structs, behaviour in methods attached to types, and reuse comes from embedding one struct in another rather than from inheritance.
Structs and methods
Capitalized fields (Name, Min, Max) are exported; last is private to the package.
InRange has a value receiver and works on a copy; Record has a pointer receiver and changes the sensor.
NewSensor is a constructor by convention, returning a pointer.
Structs with comparable fields can be compared with ==.
TempSensor embeds Device and *Sensor, so t.Label() and t.Name are promoted from them.
func (s Sensor) Record(v float64) { s.last = v } // changes a copy func (s *Sensor) Record(v float64) { s.last = v }
A value receiver gets a copy, so the change is lost. Use a pointer receiver for methods that modify the struct (or for large structs).
When should a method have a pointer receiver?
When it modifies the receiver, when the struct is large (to avoid copying), or for consistency when other methods of the type use pointer receivers.