유형 캐스팅을 용이하게 하기 위해 protobuf 메시지를 인터페이스로 언마샬링하는 것은{} proto.Unmarshal 함수가 유형의 인수를 기대하기 때문에 가능하지 않습니다. proto.Message, 구체적인 protobuf 유형을 지정하는 인터페이스 구현.
최소한 일부 상황별 정보(예: 문자열 또는 숫자)가 바이트 슬라이스와 함께 제공되는 경우 해당 정보를 사용하여 예상되는 메타데이터에 매핑할 수 있습니다. protobuf 유형을 지정하고 전달하기 전에 인스턴스화합니다. proto.Unmarshal:
func decodeWithMetadata(data []byte, identifier string) error { var message proto.Message switch identifier { case "foo": message = &mypb.Foo{} case "bar": message = &mypb.Bar{} } if err := proto.Unmarshal(data, message); err != nil { return err } log.Printf("%v\n", data) return nil }
그러나 바이트 페이로드를 전혀 알 수 없는 경우 와이어 형식의 protobuf 메시지에서 제한된 정보를 추출할 수 있는 protowire 패키지를 고려하세요. protobuf 메시지의 와이어 표현은 모호하여 의미 체계가 약하다는 점에 유의하세요.
다음 코드는 알 수 없는 protobuf 메시지를 구문 분석합니다.
type Field struct { Tag Tag Val Val } type Tag struct { Num int32 Type protowire.Type } type Val struct { Payload interface{} Length int } func parseUnknown(b []byte) []Field { // ... implementation to parse unknown protobuf messages as described in the provided answer ... }
protobuf 스키마 제공 like:
message Foo { string a = 1; string b = 2; Bar bar = 3; } message Bar { string c = 1; }
다음 코드는 파서를 사용하는 방법을 보여줍니다.
// Parse the protobuf message as byte slice b := []byte{0x0a, 0x01, 0x41, 0x12, 0x01, 0x42, 0x1a, 0x03, 0x43} fields := parseUnknown(b) for _, field := range fields { fmt.Printf("%#v\n", field) }
출력:
main.Field{Tag:main.Tag{Num:1, Type:2}, Val:main.Val{Payload:[]uint8{0x41}, Length:1}} main.Field{Tag:main.Tag{Num:2, Type:2}, Val:main.Val{Payload:[]uint8{0x42}, Length:1}} main.Field{Tag:main.Tag{Num:1, Type:2}, Val:main.Val{Payload:[]uint8{0x43}, Length:1}} main.Field{Tag:main.Tag{Num:3, Type:2}, Val:main.Val{Payload:[]main.Field{main.Field{Tag:main.Tag{Num:1, Type:2}, Val:main.Val{Payload:[]uint8{0x43}, Length:1}}}, Length:3}}
위 내용은 Go에서 알 수 없는 Protobuf 메시지를 어떻게 언마샬링하나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!