Ошибка при вызове функции, имеющей запись с полями с плавающей запятой в качестве аргумента, с использованием метода function:call.
isolated function mockFunction(record {|string operation; float operand1; float operand2;|} input) returns string{
return "mockFunction scuccessful";
}
public function main() returns error? {
string input = "{\"operation\":\"ADDITION\",\"operand1\":23.0,\"operand2\":43.0}";
map<json> & readonly inputJson = check input.fromJsonStringWithType();
any|error observation = function:call(mockFunction, inputJson);
io:println(observation);
}
Когда я попробовал вышеописанное, я получил следующую ошибку.
error: {ballerina/lang.function}IncompatibleArguments {"message":"arguments of incompatible types: argument list '(map<(json & readonly)> & readonly)' cannot be passed to function expecting parameter list '(ai.agent:record {| string operation; float operand1; float operand2; |})'"}
1 ответ
function:call()
метод попытается привестиinputJson
к ожидаемому типу аргумента. Это дает вышеуказанную ошибку, когда кастинг не удается.
https://lib.ballerina.io/ballerina/lang.value/0.0.0#fromJsonStringWithType представляет собой комбинацию и . Числа обычно преобразуются в десятичные с помощью https://lib.ballerina.io/ballerina/lang.value/0.0.0#fromJsonString .
Числа в строке JSON преобразуются в значения Ballerina десятичного типа, за исключением следующих двух случаев: если число JSON начинается с - и численно равно нулю, то оно преобразуется в значение с плавающей запятой -0,0; в противном случае, если число JSON синтаксически является целым числом и находится в диапазоне, представленном целым числом Ballerina, оно преобразуется в целое число Ballerina. Число JSON синтаксически считается целым числом, если оно не содержит ни десятичной точки, ни показателя степени.
Следовательно, в данном случаеoperand1
иoperand2
есть и нетfloat
. Вот почему актерский состав терпит неудачу.
io:println(inputJson is record {|string operation; float operand1; float operand2;|}); // false
io:println(inputJson is record {|string operation; decimal operand1; decimal operand2;|}); // true
Решение состоит в том, чтобы указать точный тип при выполнении
record {|string operation; float operand1; float operand2;|} inputRecord = check input.fromJsonStringWithType();
fromJsonStringWithType
создаст новое значение, выполняя числовые преобразования, а не приведение. ЗдесьfromJsonString
шаг все равно приведет кdecimal
значения для этих полей, ноfromJsonWithType
шаг будет обрабатывать числовое преобразование при клонировании.