types - 当使用剩余字段定义记录时,类型缩小不起作用

标签 types type-conversion ballerina

import ballerina/io;

type Vehicle record {|
    string mode;
    string color;
    string make;
    string ...; // rest field
|};

type AeroPlance record {|
    *Vehicle;
    string noOfEngines;
|};

type Helicopter record {|
    *Vehicle;
    string noOfRotors;
|};

public function main(string[] args) {
    
    AeroPlance|Helicopter flight = getFlight();
    if (flight is AeroPlance) {
        printAeroPlance(flight);
    } else {
        printHelicopter(flight);
    }
}

function getFlight() returns AeroPlance|Helicopter {
    return {mode:"Air", color:"Red", "make":  "Boeing", noOfEngines:"2"};
}

function printAeroPlance(AeroPlance aeroPlance) {
    io:println("AeroPlance:", aeroPlance);
}

function printHelicopter(Helicopter helicopter) {
    io:println("Helicopter: ", helicopter);
}

在上面的代码中,当使用剩余字段定义 Vehicle 记录时,类型缩小不会按预期工作。我收到以下编译错误。

ERROR [b.bal:(26:25,26:31)] incompatible types: expected 'Helicopter', found '(AeroPlance|Helicopter)'

但是,当从 Vehicle 记录中删除剩余字段时,此方法有效。这种行为的原因是什么?

最佳答案

这是因为目前开放记录中如何定义类型和类型缩小(Vehicle 是一个开放记录,因此 AeroPlaneHelicopter 记录也已打开)。尽管 jBallerina 实现不允许这样做,因为记录是开放的且可变的。该规范规定了类似类型的值

type AeroPlaneOrHelicopter record {|
    *Vehicle;
    string noOfRotors?;
    string noOfEngines?;
|};

适用于AeroPlane|Helicopter

因此,else block 中的类型不能缩小为 Helicopter。 如果值是封闭的或不可变的,缩小范围将按示例中的预期工作。

(AeroPlane|Helicopter) & readonly flight = getFlight().cloneReadOnly();
if flight is AeroPlane {
    printAeroPlane(flight);
} else {
    printHelicopter(flight);
}

关于types - 当使用剩余字段定义记录时,类型缩小不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77313569/

相关文章:

ballerina - Ballerina 中的继承与抽象

laravel - ballerina 中的 Composer 和 laravel 安装中使用的 Composer 有什么区别?

go - 如何测试一个接口(interface)变量的底层类型 接口(interface)变量的类型是别名

ios - HMErrorDomain Code=45 - 操作无法完成 - 语法问题

c - 使变量具有与#define 相同的类型/效果?

java - 如何将整数转换为十六进制有符号2的补码:

wso2 - 如何将 JWT 与 Ballerina 一起使用

c - 将整数存储在char数组中

swift - 为什么实例方法在 Swift 中有这种类型?

c++ - 如何在 C++ 中转换类型?