"Zusammenführen" Felder zwei Strukturen des gleichen Typs

8

Blick auf diese struct :

%Vor%

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:

  • Wenn überhaupt Reflexion benötigt wird
  • Es gibt möglicherweise einfachere Möglichkeiten, dies zu tun

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

    
faboolous 20.11.2017, 15:26
quelle

3 Antworten

8

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:

  • fehlende Werte in der Konfigurationsdatei: Standard gilt
  • Ein in der Datei angegebener Wert überschreibt die Standardkonfiguration (was auch immer)
  • explizite Überschreibungen auf Nullwerte in der Datei haben Vorrang (überschreibt die Standardkonfiguration, die nicht Null ist)

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
icza 20.11.2017, 16:15
quelle
4

Reflection wird Ihren Code langsam machen.

Für diese Struktur würde ich eine direkte Merge() -Methode wie folgt implementieren:

%Vor%

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: Ссылка

    
Alexander Trakhimenok 20.11.2017 16:03
quelle
1
  

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.

%Vor%

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.

    
mkopriva 20.11.2017 16:51
quelle

Tags und Links