Пытаясь создать сообщение JSON для API, я столкнулся с трудностями, пытаясь сделать что-то, что, на мой взгляд, было бы простым. Мне нужно было создать сообщение, подобное следующему:
{ "list": [ { "foo": 1, "bar": 2 } ] }
Однако моя первая попытка не сработала:
say to-json { foo => [ { a => 1, b => 2 } ] };
# {"foo":[{"a":1},{"b":2}]}
Попытка упростить вещи еще больше смутила меня:
say { foo => [ { a => 1 } ] };
# {foo => [a => 1]}
# Note that this is not JSON, but I expected to see curly braces
Затем я попытался использовать некоторые временные переменные, и это сработало:
my @list = { a => 1 };
say to-json { foo => @list };
# {"foo":[{"a":1}]}
my %hash = ( a => 1 );
say to-json { foo => [ %hash ] };
# {"foo":[{"a":1}]}
Что тут происходит?
И есть ли способ, которым я могу достичь желаемого результата без дополнительной временной переменной?
say to-json { foo => [ { a => 1 } ] };
должен выводить что-то вроде{"foo":[{"a":1}]}
, нет{"foo":["a":1]}
. Последняя опечатка, верно? Если нет, чтоsay $*PERL.compiler.version;
говорит?say to-json { foo => [ a => 1 ] }
результаты,{"foo":[{"a":1}]}
так что, кто знает, что я напечатал, когда я получил это, если я когда-либо сделал. Виноват!Ответы:
Вы обнаружили правило с одним аргументом . Многочисленные конструкции в Raku будут повторять аргумент, который им предоставляется. Это включает в себя
[...]
массив композитора. Вот почему, когда мы говорим:Мы получаем массив, который содержит 10 элементов, а не 1. Однако это также означает, что:
Итерирует
[1,2]
, и, следовательно, приводит к[1,2]
- как если бы внутреннего массива не было. AHash
перебирает свои пары, таким образом:На самом деле производит:
То есть в массиве есть пары. Сериализатор JSON затем сериализует каждую пару как одноэлементный объект.
Решение состоит в том, чтобы создать итерацию из одного элемента. Инфиксный
,
оператор - это то, что создает списки, поэтому мы можем использовать это:Тогда единственный аргумент, который должен быть повторен - это 1-элементный список с хешем, и вы получите желаемый результат.
Простой способ запомнить это: всегда используйте конечные запятые при указании значений списка, массива или хеша, даже с одним списком элементов, если вы на самом деле не указываете единственную итерацию, из которой нужно заполнить ее.
источник