Blick auf diese struct
:
Jetzt habe ich ein DefaultConfig
initialisiert mit einigen Werten und eins geladen von einer Datei, sagen wir FileConfig
.
Ich möchte, dass beide Strukturen zu mir zusammengeführt werden, so dass ich Config
mit dem Inhalt beider Strukturen bekomme. FileConfig
sollte alles überschreiben, was in DefaultConfig
festgelegt wurde, während FileConfig
möglicherweise nicht alle Felder enthält .
(Warum? Weil ein potenzieller Benutzer den Standardwert nicht kennt, würde das Entfernen dieses Eintrags dem Setzen des Standards entsprechen - denke ich)
Ich dachte, ich brauche dafür eine Reflexion:
%Vor%Hier bin ich mir nicht sicher:
Ein weiteres Problem, das ich hier sehe, ist, dass die Überprüfung auf Null-Werte schwierig sein kann: Was ist, wenn die überschreibende Struktur beabsichtigt, mit einem Wert von null zu überschreiben? Zum Glück, ich denke nicht, dass es für meinen Fall gilt - aber das wird eine Funktion, es kann später ein Problem werden
Vorwort: Das Paket encoding/json
verwendet die Reflektion (Paket reflect
) zum Lesen / Schreiben von Werten, einschließlich Strukturen. Andere Bibliotheken, die ebenfalls eine Reflexion verwenden (wie zum Beispiel Implementierungen von TOML und YAML), können auf ähnliche Weise (oder sogar auf die gleiche Weise) arbeiten, und somit kann das hier vorgestellte Prinzip auch auf diese Bibliotheken angewendet werden. Sie müssen es mit der von Ihnen verwendeten Bibliothek testen.
Der Einfachheit halber verwendet die hier vorgestellte Lösung die Standardbibliothek encoding/json
.
Eine elegante und "Null-Aufwand" -Lösung ist die Verwendung des encoding/json
Pakets und Unmarshalen in einen Wert der "vorbereiteten", Standardkonfiguration .
Hier geht es um alles, was Sie brauchen:
Um dies zu demonstrieren, verwenden wir diese Konfigurations-Struktur:
%Vor%Und die Standardkonfiguration:
%Vor%Nehmen wir an, die Datei enthält die folgende Konfiguration:
%Vor% Die Dateikonfiguration überschreibt die Felder S2
, S3
und S5
.
Code zum Laden der Konfiguration:
%Vor%Und die Ausgabe (versuchen Sie es auf dem Go Playground ):
%Vor%Analysieren der Ergebnisse:
S1
war im Standard Null, fehlte in der Datei, Ergebnis ist Null S2
war standardmäßig Null, wurde in Datei angegeben, Ergebnis ist der Dateiwert S3
wurde in config angegeben, wurde in der Datei auf null gesetzt, das Ergebnis ist null S4
wurde in config angegeben, fehlte in Datei, Ergebnis ist der Standardwert S5
wurde in config angegeben, in Datei angegeben, Ergebnis ist der Dateiwert Reflection wird Ihren Code langsam machen.
Für diese Struktur würde ich eine direkte Merge()
-Methode wie folgt implementieren:
Es ist fast die gleiche Menge Code, schnell und einfach zu verstehen.
Sie können diese Methode mit Uni-Tests abdecken, die Reflektion verwenden, um sicherzustellen, dass neue Felder nicht zurückgelassen werden.
Das ist der Punkt von Go - Sie schreiben mehr, um schnell & amp; leicht zu lesender Code.
Sie können auch in go generate
suchen, das die Methode für Sie aus der Strukturdefinition generiert. Vielleicht ist da schon etwas implementiert und auf GitHub verfügbar? Hier ist ein Beispiel für einen Code, der ähnlich vorgeht: Ссылка
Außerdem gibt es einige Pakete auf GitHub, von denen ich glaube, dass sie in Runtime das tun, was Sie wollen, zum Beispiel: Ссылка
Ein weiteres Problem, das ich hier sehe, ist, dass die Überprüfung auf Nullwerte erfolgen kann knifflig: Was ist, wenn die übergeordnete Struktur beabsichtigt, mit einer Null zu überschreiben Wert?
Falls Sie encoding/json
nicht verwenden können, wie es von icza oder anderen Format-Encodern angezeigt wird, die sich ähnlich verhalten wie Sie zwei verschiedene Typen.
Jetzt mit einer Funktion wie folgt:
%Vor% Sie können in params
nach Nicht-Nil-Feldern suchen und den Zeiger dereferenzieren, um den Wert in den entsprechenden Feldern in conf
festzulegen. Dadurch können Sie Felder in conf
mit Nicht-Null-Wertfeldern in params
aufheben.