[JAVA] Vorgehensweise optional in Protokollpuffern (proto3)

Protokollpuffer wurden mit "erforderlich" und "optional" in proto3 entfernt. Informationen zum Hintergrund des Löschvorgangs finden Sie in @qsonas Eintrag für eine leicht verständliche Zusammenfassung. Vielen Dank.

Das Problem ist, dass in proto3 jedes Feld einen Standardwert hat, sodass das Feld mit dem Standardwert von der Benutzerseite stammt.

  1. Ein Wert ähnlich dem absichtlich eingestellten Standardwert
  2. Standardwert nicht gesetzt, weil er nicht existiert Es bedeutet, dass Sie auch nicht beurteilen können.

Mit anderen Worten, wie man einen optionalen Wert ausdrückt.

Wie man optional ausdrückt

Es gibt mehrere Optionen, aber die Antwort von Stapelüberlauf ist hilfreich. Wird sein.

  1. Drücken Sie als separates Feld die Anwesenheit oder Abwesenheit explizit aus

schema.proto


message User {
  int32 id = 1;
  bool has_name = 2; //Zeigt das Vorhandensein oder Fehlen eines Namens an
  string name = 3;   //Tatsächlicher Wert
}

Example(Java)


User user1 = User.newBuilder()
		.setHasName(true)
		.setName("Tom")
		.build();

User user2 = User.newBuilder()
		.setHasName(false) //Der Standardwert ist false, sodass Sie keinen Satz benötigen
		.build();

user1.getHasName(); // true
user1.getName();    // "Tom"

user2.getHasName(); // false
user2.getName();    // ""
  1. Verwenden Sie eine davon

schema.proto


message User {
  int32 id = 1;
  oneof name_optional {
    string name = 2; //Wickeln Sie den Handhabungswert mit einem von ein
  }
}

Example(Java)


User user1 = User.newBuilder()
		.setName("Tom")
		.build();
User user2 = User.newBuilder()
		.build();

user1.getNameOptionalCase(); // User.NameOptionalCase.NAME
user1.getName();             // "Tom"

user2.getNameOptionalCase(); // User.NameOptionalCase.NAMEOPTIONAL_NOT_SET
user2.getName();             // ""
  1. Verwenden Sie "google / protobuf / wrappers.proto"

schema.proto


message User {
  int32 id = 1;
  google.protobuf.StringValue name = 2;
}

Example(Java)


User user1 = User.newBuilder()
		.setName(StringValue.newBuilder().setValue("Tom").build())
		.build();
User user2 = User.newBuilder()
		.build();

user1.hasName();            // true
user1.getName().getValue(); // "Tom"

user2.hasName();            // false
user2.getName().getValue(); // ""

Erwägung

Das erste, was wir alle gemeinsam haben, ist, dass Sie unabhängig von der gewählten Option nicht erzwingen können, dass es sich um einen optionalen Wert handelt. * 1 Daher ist es für jede Option erforderlich, prozedural "Prüfung auf Existenz" → "Prozess auf Wert" durchzuführen.

In 1 ist die Notation sehr einfach, aber der Compiler kann die Beziehung zwischen den beiden Feldern nicht garantieren, und es ist notwendig, sie mit Kommentaren zu unterstützen.

Im Vergleich zu 1 hat 2 den Vorteil, dass das Vorhandensein oder Fehlen von Feldern auf Compilerebene ausgedrückt werden kann, aber es ist eine etwas seltsame Verwendung, wenn eines von mehreren Feldern angenommen wird.

3 ist intuitiv und einfach im Umgang mit optionalen Werten zu bedienen, hat aber auch einige Nachteile.

Beispiel:

schema.proto


message User {
  int32 id = 1;
  Fullname fullname = 2;
}

message Fullname {
  string first_name = 1;
  string last_name = 2;
}

In einem solchen Fall wird der Wrapper beispielsweise nur mit den folgenden Typen bereitgestellt, sodass er nicht verwendet werden kann, wenn Sie jeden vollständigen Namen optional machen möchten.

DoubleValue
FloatValue
Int64Value
UInt64Value
Int32Value
UInt32Value
BoolValue
StringValue
BytesValue

Wenn Sie optionale Ausdrücke vereinheitlichen möchten, ist es daher leicht zu verstehen, mit 1 oder 2 zu vereinheitlichen.

Zusammenfassung

Protokollpuffer sind eine Schemasprache mit kompakten Spezifikationen, die sich durch niedrige Lernkosten und gute Lesbarkeit auszeichnet. Aus diesem Grund wurden jedoch einige Ausdrücke entfernt, die anderen gemeinsam sind, und ich denke, dass mehr Ausdrücke gemacht werden können, indem sie verwendet werden, während sie rechtzeitig behandelt werden.

Recommended Posts

Vorgehensweise optional in Protokollpuffern (proto3)
Umgang mit TSV-Dateien und CSV-Dateien in Ruby
Verwendung von Java Optional
Umgang mit Instanzen
So behandeln Sie Ausnahmen mit Java 8 Stream oder Optional kühl
Unterschiede im Umgang mit Zeichenfolgen zwischen Java und Perl
Wie man Lombok im Frühling benutzt
So finden Sie May'n in XPath
So blenden Sie die Bildlaufleiste in WebView aus
So führen Sie JUnit in Eclipse aus
Wie man in Ruby auf unbestimmte Zeit iteriert
Wie man Ant in Gradle ausführt
Wie man die Programmierung in 3 Monaten beherrscht
Wie man JAVA in 7 Tagen lernt
So erhalten Sie Parameter in Spark
So installieren Sie Bootstrap in Ruby
Verwendung von InjectorHolder in OpenAM
So installieren Sie jQuery in Rails 6
Wie verwende ich Klassen in Java?
So benennen Sie Variablen in Java
So setzen Sie Lombok in Eclipse
So verketten Sie Zeichenfolgen mit Java
So installieren Sie Swiper in Rails
[swift5] So legen Sie die Farbe hexadezimal fest
So implementieren Sie Suchfunktionen in Rails
So implementieren Sie die Datumsberechnung in Java
So implementieren Sie den Kalman-Filter mit Java
Mehrsprachige Unterstützung für Java Verwendung des Gebietsschemas
Verwendung des benannten Volumes in docker-compose.yml
So filtern Sie den JUnit-Test in Gradle
So fügen Sie ein Video in Rails ein
[java] Zusammenfassung des Umgangs mit char
So standardisieren Sie die Kopfzeile in Thymeleaf
Wie kann ich Spring Tool in Eclipse 4.6.3 einbinden?
So fügen Sie eine JAR-Datei in ScalaIDE hinzu
So führen Sie eine Basiskonvertierung in Java durch
Wie man Parameter in der link_to-Methode hat
Verwendung von MySQL im Rails-Tutorial
Ändern Sie die Liste <Optional <T >> in Java in Optional <Liste <T >>
So beheben Sie das Systemdatum in JUnit
So erzwingen Sie Codierungskonventionen in Java
Einbetten von Janus Graph in Java
[Rails] So konfigurieren Sie das Routing in Ressourcen
So erhalten Sie das Datum mit Java
So behandeln Sie Anmeldefehler mit devise
So implementieren Sie Ranking-Funktionen in Rails
Verwendung von Umgebungsvariablen in RubyOnRails
So implementieren Sie die asynchrone Verarbeitung in Outsystems
So veröffentlichen Sie eine Bibliothek in jCenter
So geben Sie das ID-Attribut in JSF an
Verstehe in 5 Minuten !! Wie man Docker benutzt
So überschreiben Sie Firebase-Daten mit Swift
Verwendung von credentials.yml.enc aus Rails 5.2