记录类型包含致Ballerina CSV输出列序异常,属Bug还是设计?
为什么Ballerina的类型包含会改变CSV的列顺序?
我使用Ballerina的io:fileWriteCsv函数导出两个逻辑结构一致的记录类型到CSV文件,代码如下:
import ballerina/io; type Base record {| int base1; int base2; |}; type Derived1 record {| *Base; int derived1; int derived2; |}; type Derived2 record {| int base1; int base2; int derived1; int derived2; |}; public function main() returns error? { Derived1[] d1 = [{ base1: 1, base2: 2, derived1: 3, derived2: 4 }]; Derived2[] d2 = [{ base1: 1, base2: 2, derived1: 3, derived2: 4 }]; check io:fileWriteCsv("derived1.csv", d1); check io:fileWriteCsv("derived2.csv", d2); }
我预期两个CSV文件的内容均为:
1,2,3,4
但实际导出结果为:
$ cat derived1.csv 3,4,1,2 $ cat derived2.csv 1,2,3,4
类型包含会改变CSV列的顺序,请问这是Bug还是设计如此?若是设计如此,列序规则是什么?
使用版本:
$ bal --version Ballerina 2201.2.0 (Swan Lake Update 2) Language specification 2022R3 Update Tool 1.3.10
解答
这是设计如此,并非Bug。
Ballerina记录类型的字段遍历顺序遵循以下规则:
- 对于通过类型包含(
*Base形式)定义的记录,会优先遍历当前类型直接声明的字段,之后再遍历被包含类型的字段。 - 对于直接声明所有字段的记录,字段遍历顺序与代码中声明的顺序完全一致。
对应到你的代码场景:
Derived1通过包含Base类型定义,因此导出时会先处理当前类型的derived1、derived2字段,再处理Base中的base1、base2字段,最终CSV列序为3,4,1,2。Derived2直接声明了所有字段,因此按代码中的声明顺序base1、base2、derived1、derived2导出,CSV列序符合预期的1,2,3,4。
如果需要让Derived1的导出列序与Derived2一致,可以通过io:CsvWriteOptions的columns参数显式指定列顺序,示例代码如下:
import ballerina/io; type Base record {| int base1; int base2; |}; type Derived1 record {| *Base; int derived1; int derived2; |}; public function main() returns error? { Derived1[] d1 = [{ base1: 1, base2: 2, derived1: 3, derived2: 4 }]; // 显式指定CSV列顺序 io:CsvWriteOptions options = { columns: ["base1", "base2", "derived1", "derived2"] }; check io:fileWriteCsv("derived1.csv", d1, options); }
这样导出的derived1.csv内容就会和预期一致。
内容的提问来源于stack exchange,提问作者user272735
相关产品推荐
相关产品推荐

