在 Ballerina 中访问 table 数据结构时出现问题。错误无效操作...不支持非必填字段的字段访问

Issue accessing the table data structure in Ballerina. error invalid operation... does not support field access for non required field

我一直在学习 Ballerina 并且一直在学习示例。我在 Ballerina By Example - Tables .

中的文档中遇到以下示例的问题

示例(和我的)中的代码如下:

import ballerina/io;
import ballerina/jsonutils;
import ballerina/xmlutils;

type Employee record {
    int id;
    string name;
    float salary;
};

public function main() {

    table<Employee> tbEmployee = table {
        {key id, name, salary},
        [
            {1, "Mary", 300.5},
            {2, "John", 200.5},
            {3, "Jim", 330.5}
        ]
    };

    io:print("Table Information: ");
    io:println(tbEmployee);

    Employee e1 = {id: 1, name: "Jane", salary: 300.50};
    Employee e2 = {id: 2, name: "Anne", salary: 100.50};
    Employee e3 = {id: 3, name: "John", salary: 400.50};
    Employee e4 = {id: 4, name: "Peter", salary: 150.0};

    table<Employee> tb = table {
        {key id, name, salary},
        [
            e1,
            e2
        ]
    };

    Employee[] employees = [e3, e4];

    foreach var emp in employees {
        var ret = tb.add(emp);
        if (ret is ()) {
            io:println("Adding record to table successful");
        } else {
            io:println("Adding to table failed: ", ret.reason());
        }
    }

    io:println("Table Information: ", tb);

    io:println("Using foreach: ");
    foreach var x in tb {
        io:println("Name: ", x.name);
    }

    io:println("Using while loop: ");
    while (tb.hasNext()) {
        var ret = tb.getNext();
        io:println("Name: ", ret.name);
    }

    json retValJson = jsonutils:fromTable(tb);
    io:println("JSON: ", retValJson.toJsonString());

    xml retValXml = xmlutils:fromTable(tb);
    io:println("XML: ", retValXml);

    int|error count = tb.remove(isHigherSalary);
    io:println("Deleted Count: ", count);

    io:println(tb);
}

function isHigherSalary(Employee emp) returns boolean {
    return emp.salary > 300.0;
}

当我 运行 它时,我遇到以下行 (59) 的问题:

io:println("Name: ", ret.name);

error: .::tables_orig.bal:59:30: invalid operation: type 'record {| anydata...; |}' does not support field access for non-required field 'name'

我正在使用 Ballerina 1.0.5。我该如何解决这个问题?

我发现了问题。我使用的是 Ballerina 1.0.5,网站上的代码适用于 2019 年 12 月 19 日刚刚发布的 1.1.0,该网站有一个错误,当您更改版本号时 code/section 不会改变下拉菜单并转到以前的版本。

Ballerina By Example website 中列出的示例中的语法不向后兼容 1.1.0 之前的先前版本。当我将 ret.name 更改为 ret.get("name"):

时,代码在 1.0.5 中有效
while (tb.hasNext()) {
        var ret = tb.getNext();
        io:println("Name: ", ret.get("name")); // changed from ret.name in the example
    }

这让我感到困惑,因为在之前的 foreach 循环中,它在调用 ret.name 时起作用,即

io:println("Using foreach: ");
foreach var x in tb {
    io:println(typeof tb);
    io:println("Name: ", x.name); // this works
}

错误原因

在使用 typeof 检查两个循环中变量 ret 的类型后,这一点变得很明显:

io:println("Using foreach: ");
    foreach var x in tb {
        io:println("Type of tb is : ", typeof tb);
        io:println("Name: ", x.name); 
        break;
    }

    io:println("Using while loop: ");
    while (tb.hasNext()) {
        var ret = tb.getNext();
        io:println("Type of var ret = tb.getNext() is : ", typeof ret);
        io:println("Name: ", ret.get("name"));
        break;
    }

输出:

Using foreach: 
Type of tb is : typedesc table<Employee>
Name: Jane
Using while loop: 
Type of var ret = tb.getNext() is : typedesc Employee
Name: John

字段访问在类型为 table 时支持,就像在 foreach 循环中一样,但它不起作用,因为 ret 的类型是我们之前定义的 Employee

我希望这对面临同样问题的其他人有所帮助。

理想情况下,字段访问应该与 getNext() 一起使用,但在如何为 getNext() 调用确定类型方面存在问题。 https://github.com/ballerina-platform/ballerina-lang/commit/8196d93023ba12958dfdd5f28a70c8da2147bf48 现已修复此问题,Ballerina 1.1.0 将提供此修复程序,该版本即将发布。