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

问题描述 投票:0回答:1
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);
}

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

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

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

types type-conversion ballerina
1个回答
0
投票

这是因为目前开放记录中如何定义类型和类型缩小(车辆是开放记录,因此飞机和直升机记录也是开放的)。尽管 jBallerina 实现不允许这样做,因为记录是开放的且可变的。规范规定了类似

类型的值
type AeroPlaneOrHelicopter record {|
    *Vehicle;
    string noOfRotors?;
    string noOfEngines?;
|};

有效期为

AeroPlane|Helicopter

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

(AeroPlane|Helicopter) & readonly flight = getFlight().cloneReadOnly();
if flight is AeroPlane {
    printAeroPlane(flight);
} else {
    printHelicopter(flight);
}
© www.soinside.com 2019 - 2024. All rights reserved.