You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

含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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 13:21:18