[
https://issues.apache.org/jira/browse/THRIFT-5801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18112671#comment-18112671
]
Sylwester Lachiewicz commented on THRIFT-5801:
----------------------------------------------
We investigated this across 6 language implementations (Go, Rust, Java, C++,
Python, Node.js) to compare wire representation and runtime behavior.
h3. Cross-Language Comparison for optional list<string> f_1 = ["a", "b"]
|| Language || Field Representation || Default State on Init || Serialized Wire
Output || Read / Accessor Value ||
| Go | *[]string | nil (unset) | 00 (Empty struct, 0 bytes) | GetF_1() returns
["a", "b"] |
| Rust | Option<Vec<String>> | None (unset) | 00 (Empty struct, 0 bytes) | None
(default accessor returns ["a", "b"]) |
| C++ | std::vector<std::string> | ["a", "b"] (__isset = true) |
0f00010b00000002... (19 bytes) | ["a", "b"] |
| Java | List<String> | ["a", "b"] | 0f00010b00000002... (19 bytes) | ["a",
"b"] |
| Python | list | ['a', 'b'] | 0f00010b00000002... (19 bytes) | ['a', 'b'] |
| Node.js | Array | ['a', 'b'] | 0f00010b00000002... (19 bytes) | ['a', 'b'] |
h3. Findings
1. *Bandwidth Efficiency & IDL Spec Conformance*:
According to the Thrift IDL specification (doc/specs/idl.md):
{quote}
*optional*
- Write: Optional fields are only written when they are set
- Read: Optional fields may, or may not be part of the input stream.
- Default values: are written when the isset flag is set
{quote}
Both Go and Rust distinguish between an unset optional field and an explicitly
set field. Leaving the optional pointer / Option unset prevents serializing and
transmitting default collections over the network on every RPC call when the
caller never modified the field.
2. *Interoperability*:
When Go or Rust serializes an empty struct (00), receiving endpoints in C++,
Java, Python, and Node.js still populate the default value ["a", "b"] during
deserialization. The logical data seen by the receiver application is identical
across all languages.
3. *Accessor Method*:
In Go, callers access the default value through the generated getter
`GetF_1()`, which returns `[]string{"a", "b"}` when the pointer is nil.
This behavior is compliant with Thrift IDL write semantics and is working as
designed.
> Go does not handle the default value of list type correctly
> -----------------------------------------------------------
>
> Key: THRIFT-5801
> URL: https://issues.apache.org/jira/browse/THRIFT-5801
> Project: Thrift
> Issue Type: Bug
> Components: Go - Compiler
> Affects Versions: 0.19.0, 0.20.0
> Reporter: Team_RPCtester
> Priority: Major
>
> Hi,
> We discover an inconsistent behavior illustrated by the following example.
> {code:java}
> namespace go commonResourcestruct
> StructClass_0 {
> 1: optional list<string, string> f_1 = ["a", "b"],
> }
> service DataService {
> StructClass_0 Method_1(1: StructClass_0 agr_method_1)
> } {code}
> When default values are set for optional container type fields (e.g., lists,
> sets), these fields are not automatically initialized in Go if not explicitly
> set, whereas in other languages, these container type fields are
> automatically initialized according to the default values. For example, in
> the Go client side, our code are as follows:
> {code:java}
> agr_method_1_0 := commonResource.NewStructClass_0()
> fmt.Println(agr_method_1_0)
> // method_1_re_agr_method_1_0: StructClass_0({F_1:<nil>}) {code}
> In the Python client side:
> {code:java}
> agr_method_1 = StructClass_0()
> print(agr_method_1)
> # agr_method_1: StructClass_0(f_1-[’a’,’b’]) {code}
> In Go, the field f_1 is nil, while in Python, the field f_1 is automatically
> set to its default value ['a', 'b'].
> Can you help check the issue?
> Thank you.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)