含rest字段的Ballerina Record类型收窄失效原因咨询
Ballerina带rest字段的record类型收窄问题
以下是出现问题的Ballerina代码:
import ballerina/io; type Vehicle record {| string mode; string color; string make; string ...; // rest字段 |}; 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)'
但移除Vehicle中的rest字段后,代码可以正常编译运行,原因如下:
- 当
Vehicle包含rest字段时,AeroPlance和Helicopter不再是互斥类型。因为rest字段允许实例存在额外的字符串类型键值对,一个实例可以同时拥有noOfEngines和noOfRotors字段,同时满足两个类型的结构要求。 - Ballerina的类型收窄逻辑要求分支中的类型必须互斥:只有当两个类型不可能有共同实例时,编译器才能在
else分支确定剩余类型。而带rest字段的情况下,AeroPlance|Helicopter的并集中存在同时属于两个类型的实例,所以编译器无法在else分支将flight的类型收窄为Helicopter,只能保留原并集类型,导致类型不兼容错误。 - 移除rest字段后,
Vehicle不允许存在额外字段,AeroPlance和Helicopter的结构变得互斥——一个实例不可能同时拥有noOfEngines和noOfRotors字段。此时编译器可以确定,if分支排除AeroPlance后,else分支的实例必然是Helicopter,类型收窄就能正常工作。
内容的提问来源于stack exchange,提问作者MOHAMED SABTHAR
相关产品推荐
相关产品推荐

