google/protocol-buffers

Protocol Buffers : Language Guide (proto3) - Oneof

C/H 2018. 9. 3. 08:30

Index

Oneof

If you have a message with many fields and where at most one field will be set at the same time, you can enforce this behavior and save memory by using the oneof feature.
여러 개의 필드가 있는 메시지가 있고 최대 하나의 필드가 동시에 설정되는 경우 이 동작을 수행하고 기능 중 하나를 사용하여 메모리를 저장할 수 있다.

Oneof fields are like regular fields except all the fields in a oneof share memory, and at most one field can be set at the same time. Setting any member of the oneof automatically clears all the other members. You can check which value in a oneof is set (if any) using a special case() or WhichOneof() method, depending on your chosen language.
두 필드 중 하나는 공유 메모리에 있는 모든 필드를 제외한 일반 필드와 비슷하며, 최대 한 개의 필드를 동시에 설정할 수 있다. 한 개의 구성원을 설정하면 다른 구성원이 자동으로 모두 지워진다. 선택한 언어에 따라 특수 케이스() 또는 WhoOneof() 방법을 사용하여 한 개 중 어느 값이 설정되었는지 확인할 수 있다.

Using Oneof Oneof 사용

To define a oneof in your .proto you use the oneof keyword followed by your oneof name, in this case test_oneof:
.proto에서 하나를 정의하려면 키워드 중 하나와 이름 하나를 차례로 사용합니다. 이 경우 test_oneof:

message SampleMessage {
    oneof test_oneof {
        string name = 4;
        SubMessage sub_message = 9;
    }
}

You then add your oneof fields to the oneof definition. You can add fields of any type, but cannot use repeated fields.
그런 다음 정의 중 하나에 필드 하나를 추가합니다. 모든 유형의 필드를 추가할 수 있지만 반복된 필드는 사용할 수 없다.

In your generated code, oneof fields have the same getters and setters as regular fields. You also get a special method for checking which value (if any) in the oneof is set. You can find out more about the oneof API for your chosen language in the relevant API reference.
생성된 코드에서 필드 중 하나는 일반 필드와 동일한 게이터 및 세터를 가진다. 또한 한 값에서 설정된 값(있는 경우)을 확인하는 특수 방법도 제공된다. 선택한 언어에 대한 API에 대한 자세한 내용은 관련 API 참조에서 확인할 수 있다.

Oneof Features Oneof 기능

  • Setting a oneof field will automatically clear all other members of the oneof. So if you set several oneof fields, only the last field you set will still have a value.
    필드 중 하나를 설정하면 한 필드의 다른 구성원이 자동으로 삭제된다. 따라서 필드 중 하나를 여러 개 설정한 경우에도 마지막으로 설정한 필드에만 값이 유지된다.
    SampleMessage message;
    message.set_name("name");
    CHECK(message.has_name());
    message.mutable_sub_message();   // Will clear name field.
    CHECK(!message.has_name());
    
  • If the parser encounters multiple members of the same oneof on the wire, only the last member seen is used in the parsed message.
    파서가 와이어에서 동일한 멤버의 여러 멤버를 발견하면 마지막으로 표시된 멤버만 구문 분석된 메시지에 사용된다.
  • A oneof cannot be repeated.
    둘 중 하나는 반복할 수 없다.
  • Reflection APIs work for oneof fields.
    반사 API는 필드 중 하나에서 작동합니다.
  • If you're using C++, make sure your code doesn't cause memory crashes. The following sample code will crash because sub_message was already deleted by calling the set_name() method.
    C++를 사용하는 경우 코드가 메모리 충돌을 일으키지 않는지 확인한다. set_name() 메서드를 호출하여 하위_message가 이미 삭제되었기 때문에 다음 샘플 코드가 충돌한다.
    SampleMessage message;
    SubMessage* sub_message = message.mutable_sub_message();
    message.set_name("name");      // Will delete sub_message
    sub_message->set_...            // Crashes here
    
  • Again in C++, if you Swap() two messages with oneofs, each message will end up with the other’s oneof case: in the example below, msg1 will have a sub_message and msg2 will have a name.
    C++에서 두 개의 메시지를 한 개의 메시지로 교환하면 각 메시지는 다른 하나의 경우로 끝납니다. 아래 예에서 msg1에는 sub_message와 ms가 있다.
    SampleMessage msg1;
    msg1.set_name("name");
    SampleMessage msg2;
    msg2.mutable_sub_message();
    msg1.swap(&msg2);
    CHECK(msg1.has_sub_message());
    CHECK(msg2.has_name());
    

Backwards-compatibility issues 역호환성 문제

Be careful when adding or removing oneof fields. If checking the value of a oneof returns None/NOT_SET, it could mean that the oneof has not been set or it has been set to a field in a different version of the oneof. There is no way to tell the difference, since there's no way to know if an unknown field on the wire is a member of the oneof.
필드 중 하나를 추가하거나 제거할 때 주의하라. 한 값의 값을 확인하면 없음/아니오_SET가 반환되는 경우, 한 값이 설정되지 않았거나 다른 버전의 필드에 설정되었음을 의미할 수 있다. 그 차이를 구별할 방법은 없다. 왜냐하면 철사의 알려지지 않은 장이 그 중 하나에 속하는지 알 수 있는 방법이 없기 때문이다.

반응형