google/protocol-buffers

Protocol Buffers : Language Guide (proto3) - Enumerations

C/H 2018. 8. 27. 08:30

Index

Enumerations 열거형

When you're defining a message type, you might want one of its fields to only have one of a pre-defined list of values. For example, let's say you want to add a corpus field for each SearchRequest, where the corpus can be UNIVERSAL, WEB, IMAGES, LOCAL, NEWS, PRODUCTS or VIDEO. You can do this very simply by adding an enum to your message definition with a constant for each possible value.
메시지 유형을 정의할 때 해당 필드 중 하나에 미리 정의된 값 목록 중 하나만 포함하면 된다. 예를 들어, 각 SearchRequest에 대한 말뭉치 필드를 추가하려고 한다. 여기서 말뭉치는 UNIVERSAL, WEB, IMAGES, LOCAL, NEWS, VDUCCTS입니다. 가능한 각 값에 대해 일정한 메시지 정의에 열거를 추가하면 매우 간단하게 이 작업을 수행할 수 있다.

In the following example we've added an enum called Corpus with all the possible values, and a field of type Corpus:
다음 예에서는 가능한 모든 값을 가진 코러스라는 열거형과 코러스 유형의 필드를 추가했습니다.

message SearchRequest {
    string query = 1;
    int32 page_number = 2;
    int32 result_per_page = 3;
    enum Corpus {
        UNIVERSAL = 0;
        WEB = 1;
        IMAGES = 2;
        LOCAL = 3;
        NEWS = 4;
        PRODUCTS = 5;
        VIDEO = 6;
    }
    Corpus corpus = 4;
}

As you can see, the Corpus enum's first constant maps to zero: every enum definition must contain a constant that maps to zero as its first element. This is because:
보는 바와 같이, 코러스 엔룸의 첫 번째 상수 맵은 0이다. 모든 열거형 정의는 첫 번째 요소로 0으로 매핑되는 상수를 포함해야 한다. 그 이유는 다음과 같습니다.

There must be a zero value, so that we can use 0 as a numeric default value. The zero value needs to be the first element, for compatibility with the proto2 semantics where the first enum value is always the default. You can define aliases by assigning the same value to different enum constants. To do this you need to set the allow_alias option to true, otherwise the protocol compiler will generate an error message when aliases are found.
0을 숫자 기본값으로 사용할 수 있도록 0 값이 있어야 한다. 첫 번째 열거값이 항상 기본값인 양성자2 의미론과의 호환성을 위해 0 값이 첫 번째 요소여야 한다. 동일한 값을 다른 열거형 상수에 할당하여 별칭을 정의할 수 있다. 이렇게 하려면 allow_alias 옵션을 true로 설정해야 한다. 그렇지 않으면 프로토콜 컴파일러가 별칭을 찾으면 오류 메시지를 생성한다.

enum EnumAllowingAlias {
    option allow_alias = true;
    UNKNOWN = 0;
    STARTED = 1;
    RUNNING = 1;
}
enum EnumNotAllowingAlias {
    UNKNOWN = 0;
    STARTED = 1;
    // RUNNING = 1;  // Uncommenting this line will cause a compile error inside Google and a warning message outside.
    // RUNNING = 1;  // 이 라인을 따르지 않으면 Google에 컴파일 오류가 발생하고 경고 메시지가 표시된다.
}

Enumerator constants must be in the range of a 32-bit integer. Since enum values use varint encoding on the wire, negative values are inefficient and thus not recommended. You can define enums within a message definition, as in the above example, or outside – these enums can be reused in any message definition in your .proto file. You can also use an enum type declared in one message as the type of a field in a different message, using the syntax MessageType.EnumType.
열거자 상수는 32비트 정수 범위에 있어야 한다. 열거형 값은 와이어에서 varint 인코딩을 사용하기 때문에 음수 값은 비효율적이므로 권장되지 않는다. 위의 예와 같이 메시지 정의 내에서 또는 외부에서 열거형을 정의할 수 있다. – 이러한 열거형은 .proto 파일의 모든 메시지 정의에서 재사용할 수 있다. 또한 MessageType.EnumType구문을 사용하여 한 메시지에서 선언한 열거형 유형을 다른 메시지의 필드 유형으로 사용할 수 있다.

MessageType.EnumType.

When you run the protocol buffer compiler on a .proto that uses an enum, the generated code will have a corresponding enum for Java or C++, a special EnumDescriptor class for Python that's used to create a set of symbolic constants with integer values in the runtime-generated class.
열거를 사용하는 .proto에서 프로토콜 버퍼 컴파일러를 실행하면 생성된 코드에는 Python에 사용되는 기호 정수인 Java 또는 C++에 해당하는 EnumDescriptor 클래스가 포함된다.

During deserialization, unrecognized enum values will be preserved in the message, though how this is represented when the message is deserialized is language-dependent. In languages that support open enum types with values outside the range of specified symbols, such as C++ and Go, the unknown enum value is simply stored as its underlying integer representation. In languages with closed enum types such as Java, a case in the enum is used to represent an unrecognized value, and the underlying integer can be accessed with special accessors. In either case, if the message is serialized the unrecognized value will still be serialized with the message.
메시지를 비일관화하면 인식되지 않는 열거형 값이 메시지에 보존되지만, 메시지를 감식할 때 표시되는 방법은 언어에 따라 다르다. C++ 및 Go와 같이 지정된 기호 범위를 벗어나는 값으로 enum type을 지원하는 언어에서 알 수 없는 enum 값은 단순히 기본 정수 표현으로 저장된다. Java와 같이 닫힌 열거형을 사용하는 언어에서는 열거형에서 인식할 수 없는 값을 나타내는 경우가 사용되며, 특수 접근자를 사용하여 기본 정수에 액세스할 수 있다. 두 경우 모두 메시지가 직렬화되더라도 인식할 수 없는 값은 여전히 메시지와 함께 직렬화된다.

For more information about how to work with message enums in your applications, see the generated code guide for your chosen language.
응용프로그램에서 메시지 열거를 처리하는 방법에 대한 자세한 내용은 선택한 언어의 생성된 코드 가이드를 참조하라.

Reserved Values 예약된 값

If you update an enum type by entirely removing an enum entry, or commenting it out, future users can reuse the numeric value when making their own updates to the type. This can cause severe issues if they later load old versions of the same .proto, including data corruption, privacy bugs, and so on. One way to make sure this doesn't happen is to specify that the numeric values (and/or names, which can also cause issues for JSON serialization) of your deleted entries are reserved. The protocol buffer compiler will complain if any future users try to use these identifiers. You can specify that your reserved numeric value range goes up to the maximum possible value using the max keyword.
열거형 항목을 완전히 제거하거나 주석을 통해 열거형 유형을 업데이트하면 이후 사용자가 해당 유형을 업데이트할 때 숫자 값을 다시 사용할 수 있다. 이 경우 나중에 데이터 손상, 개인 정보 버그 등을 포함하여 동일한 .proto의 이전 버전을 로드하는 경우 심각한 문제가 발생할 수 있다. 이렇게 하지 않도록 하는 한 가지 방법은 삭제된 항목의 숫자 값(및/또는 이름, JSON 직렬화에 문제가 발생할 수 있음)을 예약하도록 지정하는 것이다. 프로토콜 버퍼 컴파일러는 향후 사용자가 이러한 식별자를 사용하려고 할 경우 불만을 제기할 것이다. 예약된 숫자 값 범위가 최대 키워드를 사용하여 가능한 최대값까지 올라가도록 지정할 수 있다.

enum Foo {
    reserved 2, 15, 9 to 11, 40 to max;
    reserved "FOO", "BAR";
}

Note that you can't mix field names and numeric values in the same reserved statement. 필드 이름과 숫자 값을 동일한 예약 문에서 함께 사용할 수 없다.

반응형