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)'
但是,当从车辆记录中删除剩余字段时,这才有效。这种行为的原因是什么?
这是因为目前开放记录中如何定义类型和类型缩小(车辆是开放记录,因此飞机和直升机记录也是开放的)。尽管 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);
}