使用function:call调用含float字段record参数的函数时出错
解决Ballerina中function:call调用带float字段record参数的类型不兼容问题
问题原因
报错核心是参数类型不匹配:fromJsonStringWithType()返回的是map<json> & readonly类型对象,而mockFunction期望接收结构明确的匿名record类型,两者无法直接兼容,导致function:call无法完成参数传递。
解决方案
需要先将JSON转换后的map对象转换成目标record类型,再传递给function:call。推荐定义命名record提升代码可读性,具体步骤如下:
定义命名record类型
将原本的匿名record抽成命名类型,明确参数结构:type OperationInput record {| string operation; float operand1; float operand2; |};修改函数参数类型
把mockFunction的参数类型替换为上面定义的命名record:isolated function mockFunction(OperationInput input) returns string { return "mockFunction successful"; }转换JSON map为目标record
在main函数中,使用cloneWithType()将只读JSON map转换为OperationInput类型:public function main() returns error? { string input = "{\"operation\":\"ADDITION\",\"operand1\":23.0,\"operand2\":43.0}"; map<json> & readonly inputJson = check input.fromJsonStringWithType(); // 转换为目标record类型 OperationInput opInput = check inputJson.cloneWithType(); any|error observation = function:call(mockFunction, opInput); io:println(observation); }
替代方案(使用匿名record)
若不想定义命名record,也可直接在转换时指定匿名record类型:
public function main() returns error? { string input = "{\"operation\":\"ADDITION\",\"operand1\":23.0,\"operand2\":43.0}"; map<json> & readonly inputJson = check input.fromJsonStringWithType(); // 直接转换为匿名record类型 var opInput = check inputJson.cloneWithType(record {|string operation; float operand1; float operand2;|}); any|error observation = function:call(mockFunction, opInput); io:println(observation); }
原理说明
cloneWithType()方法会验证JSON map的结构和字段类型是否与目标record匹配,匹配成功则返回对应record实例,失败则返回错误。通过这一步转换,参数类型完全符合mockFunction的要求,function:call即可正常调用。
内容的提问来源于stack exchange,提问作者Dulmina
相关产品推荐
相关产品推荐

