Go Home Page
Die Programmiersprache Go
© 2014 Hans-Werner Heinzen @ Bitloeffel.de
Die Nutzung dieses Werks ist unter den Bedingungen der "Creative Commons Namensnennung - Keine Bearbeitungen 4.0 International"-Lizenz erlaubt.

Starke Typen

Dieser Aufsatz macht auf einen hilfreichen Aspekt von Datentypen aufmerksam.

Vor kurzem habe ich gleich mehrere Tage gebraucht, um nur einen Datenpflegedialog zu entwanzen. Immer wieder kamen falsche Daten an der Oberfläche an ... Oder eine Fehlermeldung, dass irgendwas nicht gefunden worden sei ... Obwohl es doch da war! ... Programmiereralltag.

Zugegeben, der genannte Dialog ist nicht ganz trivial. Auf der Bedienoberfläche gibt es Felder für Texteingaben, verschiedene Check- und Comboboxen und mehrere Listen. Die Oberfläche (C++/Qt) kommuniziert über JSON mit einem Logikserver (Go), dieser wiederum wiederum über JSON mit einem Datenserver (Go), der über SQL eine Datenbank (Sqlite) bedient.

Kompliziert? Ja, vielleicht. Aber die Oberfläche funktionierte schon, und die Kommunikation zwischen den vier Ebenen auch. Nein, die Fehler steckten alle in der Logik.

Und dann stellte sich heraus, dass die meisten dieser Fehler sich sehr ähnlich waren. Ursache war dann immer eine Kombination aus Variablen mit verwechselbaren Typen und Tippfehlern, wie sie typischerweise entstehen durch Copy und Paste und Find 'n' Replace, und dann doch noch was vergessen. (Über diese Sorte von Fehlern schreibt Andrey Karpov in "The Last Line Effect".)

Sehen wir uns mal einen Ausschnitt aus dem Datenmodell an:

Datenmodell

Fehlzeit ist jeweils ein Zeitraum (von, bis) und mit Fehlgrund ist sowas wie "Urlaub" oder "Krankheit" gemeint.

Im Programm hat man es dann mit Variablen wie Mitarbeiter.ID, Fehlzeit.ID, Fehlzeit.MiID, Fehlzeit.FgID und Fehlgrund.ID zu tun. Es sind dies Zugriffsschlüssel auf Datenbanktabellen ... Und alle sind vom Typ int32 ... Und niemand hindert uns daran, z.B. eine Mitarbeiter-ID versehentlich als Fehlgrund-ID zu benutzen ... und damit eine mittlere Katastrophe auszulösen:

Fehlzeit.FgID = Mitarbeiter.ID

Doch halt! Es gibt jemanden, der uns hindern könnte. Der Compiler nämlich.

In einer Sprache mit strenger Typprüfung, wie es Go eine ist, weist man sachlich verschiedenen Variablen entsprechend verschiedene Typen zu. Also in unserem Beispiel deklarieren wir zuerst die Typen:

type (
    MIID int32 // identifiziert einen Mitarbeiter
    FZID int32 // identifiziert eine Fehlzeit
    FGID int32 // identifiziert einen Fehlgrund
)

Und dann die Variablen:

var Mitarbeiter struct (
    ID MIID
    // ...
)

var Fehlgrund struct (
    ID FGID
    // ...
)

var Fehlzeit struct (
    ID   FZID
    MiID MIID
    FgID FGID
    // ...
)

Und das war's schon. Der Compiler meldet jetzt:

...: cannot use Mitarbeiter.ID (type MIID) as type FGID in assignment

Der Compiler haut uns also auf die Finger, wenn wir nach einem Fehlgrund mit einer Mitarbeiter-ID suchen wollen ... oder wenn wir Äpfel mit Birnen vergleichen wollen ... und eine ganze Fehlerklasse verschwindet.

Bei Schlüsselfeldern wie den genanntes IDs sind eigene Typen besonders ertragreich. Aber man kann genausogut auch ganz belanglose Variablen absichern. Ein Mitarbeitername ist etwas komplett anderes als ein Projektname; also bekommt jener den Typ MINAME und dieser PJNAME, und alles wird gut.

Juni 2014