Warnungen im strengen Modus verstehen

Warnungen im strengen Modus verstehen

> LeekScript-Tutorial

Du hast dich entschieden, in den strengen Modus zu wechseln, und der Editor überschüttet dich mit lauter Warnungen, die es vorher nicht gab. Keine Panik, genau das ist der Sinn des strengen Modus: Er ist weniger nachsichtig und lässt vor allem bei der Typisierung weniger Freiheiten. Schauen wir uns einige häufige Warnungen an, um erst einmal zu verstehen, welches Problem gemeldet wird, und dann Lösungen dafür zu finden.

Gefährliche Umwandlung des Typs „real“ in „integer“

Ein erster einfacher Fall: Ich möchte das Ergebnis einer Berechnung in einer Variablen vom Typ integer speichern.

Das Problem ist hier, dass die Funktion sqrt immer einen Wert vom Typ real zurückgibt, auch wenn sqrt(4) mathematisch 2 ergibt. Eine reelle Zahl passt aber nicht verlustfrei in eine Variable vom Typ integer: Was soll zum Beispiel mit den Nachkommastellen von sqrt(2) geschehen? Der Compiler verlangt deshalb eine ausdrückliche Entscheidung. Es gibt verschiedene Lösungen für diese Warnung:

Gefährliche Umwandlung des Typs „integer?“ in „integer“

Ein anderer Fall: Ich habe ein assoziatives Array (Map) aus ganzen Zahlen, wie unten definiert, und möchte einen Wert daraus ebenfalls in einer Variablen vom Typ integer speichern; eigentlich sollten die Typen doch übereinstimmen...

Warum sagt uns die Warnung, dass mapEntier[0] vom Typ „integer?“ ist und nicht einfach „integer“? Zur Erinnerung: Das „?“ am Ende eines Typs bedeutet, dass dieser Typ auch den Wert null akzeptiert; es entspricht „integer | null“. Warum also könnte mein assoziatives Array einen null-Wert zurückgeben, wo es laut seinem Typ doch nur integer enthält? Wenn man einen Wert aus einem assoziativen Array lesen will, muss man ihm einen Schlüssel übergeben, hier „0“ in eckigen Klammern. Dieser Schlüssel muss den im assoziativen Array festgelegten Typ haben, hier integer, so weit also alles in Ordnung. Aber nichts garantiert dem Editor, dass der Schlüssel im assoziativen Array existiert, und wenn man ein assoziatives Array mit einem nicht vorhandenen Schlüssel liest, ist die Rückgabe immer null. Deshalb ist die Rückgabe eines Zugriffs auf ein assoziatives Array über seinen Schlüssel immer nullable. Sehen wir uns nun an, wie man dieses Problem löst, um keine Warnungen mehr zu bekommen:

Gefährliche Umwandlung des Typs „(Array, Function any>)“ in „()“

In diesem Fall habe ich eine Liste ganzer Zahlen, die ich sortieren möchte, eigentlich nichts Kompliziertes; ich übernehme sogar das Beispiel aus der Dokumentation

Trotzdem bekomme ich zwei Warnungen für diese eine Zeile. Fangen wir mit der ersten an: Sie steht in Klammern, was bedeutet, dass das Problem bei den Parametern der Funktion liegt, die nicht der erwarteten Signatur entsprechen. Sehen wir uns die Dokumentation von arraySort an, um die Signatur zu prüfen: Function real | integer> => Array> Es ist also eine Funktion, die 2 Parameter erwartet: als ersten Parameter eine Liste und als zweiten Parameter eine Funktion, die ebenfalls 2 Parameter nimmt und eine ganze oder reelle Zahl zurückgibt. Als ersten Parameter übergeben wir tatsächlich eine Liste, das passt also; das Problem liegt somit beim zweiten Parameter: Wir übergeben eine Funktion mit der Signatur Function any>, während arraySort Function real | integer> erwartet; der Rückgabetyp ist nicht der erwartete.

Das Typisierungsproblem der Callback-Funktion ist gelöst, bleibt noch die zweite Warnung. Wie eben gesehen, ist die Rückgabe der Funktion arraySort kein Array\, wie wir es für unsere Variable erwarten, sondern einfach Array; man muss die Rückgabe also ausdrücklich casten, um dieses Problem zu beheben.