从我读到的内容来看,perl没有整数或字符串的实数类型,对于他来说,任何$变量都是标量。
最近我遇到了一个旧脚本,它生成了另一个进程所需的JSON对象,其中JSON中的值必须是整数,经过一些调试我发现因为一个简单的打印函数:
JSON :: encode_json
生成一个字符串而不是一个整数,这是我的例子:
use strict;
use warnings;
use JSON;
my $score1 = 998;
my $score2 = 999;
print "score1: ".$score1."\n";
my %hash_object = ( score1 => $score1, score2 => $score2 );
my $json_str = encode_json(\%hash_object); # This will work now
print "$json_str";
它输出:
score1: 998
{"score1":"998","score2":999}
不知何故,perl变量有一个类型,或者至少这是JSON :: encode_json的思考方式。
有没有办法以编程方式查找此类型以及为什么在进行上述连接操作时更改此类型?
答案 0 :(得分:7)
首先,它有点不正确。是的,每个值都是标量,但标量具有单独的数值和字符串值。这就是你需要知道的关于这个特定问题的所有内容,所以我将详细说明。
你真正需要的是看一下MAPPING / PERL - > JSON
模块的文档的JSON / simple scalars部分:
JSON :: XS和JSON :: PP会将未定义的标量编码为JSON null 值,最后一次在字符串上下文中使用的标量 编码为JSON字符串,以及其他任何数字值。
(这里的文档实际上有点错误。它不是“最后一次在字符串上下文中使用”它应该“在字符串上下文中使用过” - 一旦标量获得字符串值,它就不会消失直到你明确地将新数字写入其中。)
您可以通过字符串化将类型强制为字符串:
my $x = 3.1; # some variable containing a number
"$x"; # stringified
$x .= ""; # another, more awkward way to stringify
print $x; # perl does it for you, too, quite often
顺便说一下,上面的评论正是为什么你的998转向字符串。
您可以通过编号强制类型为数字:
my $x = "3"; # some variable containing a string
$x += 0; # numify it, ensuring it will be dumped as a number
$x *= 1; # same thing, the choice is yours.
答案 1 :(得分:3)
Perl标量可以同时保存字符串和标量值。其中任何一个都作为JSON值有效,因此如果有一个字符串值总是使用
这是一个罕见的问题,因为大多数软件应该接受数字的引用或不引用的表示。 JSON文档中的 Everything 最初是一个字符串,通过要求模块在向您提供数据之前应用任意字符串→浮点转换,可能会丢失重要数据
但是如果你真的需要写一个没有引号的数值,那么你可以强制标量表现为数字类型:只需向它添加零。
同样,如果标量变量只包含一个数字变量,那么只需将其用作字符串,就可以强制Perl生成并存储其等效字符串。对我来说最明显的方法是用引号将其括起来
此代码似乎可以执行您想要的操作
use strict;
use warnings 'all';
use feature 'say';
use JSON;
my ($score1, $score2) = (998, 999);
print "score1: $score1\n";
my %data = ( score1 => 0+$score1, score2 => 0+$score2 );
say encode_json(\%data);
score1: 998
{"score1":998,"score2":999}