如何让Perl数字常量即使参与字符串拼接,序列化JSON仍为数字?
Perl常量参与字符串拼接后JSON序列化类型异常的解决办法
当使用use constant定义数字常量时,单独用于JSON序列化会被识别为数字,但如果该常量参与过字符串拼接操作,后续序列化时会被转为字符串类型,以下是具体现象和解决方法:
符合预期的代码示例
#!/usr/bin/perl use strict; use warnings FATAL => 'all'; use feature qw(say); use constant MY_CONSTANT => 42; use JSON::XS; say encode_json { value => MY_CONSTANT };
输出结果:
{"value":42}
出现类型异常的代码示例
当常量参与字符串拼接后,JSON序列化结果中数字变为字符串:
#!/usr/bin/perl use strict; use warnings FATAL => 'all'; use feature qw(say); use constant MY_CONSTANT => 42; use JSON::XS; say encode_json { value => MY_CONSTANT }; my $smth = 'asdf' . MY_CONSTANT;
输出结果:
{"value":"42"}
解决办法
use constant定义的本质是子例程,Perl的SV标量会缓存上次使用的上下文,字符串拼接会强制其进入字符串上下文并保留状态,可通过以下方式避免:
使用
Readonly模块定义常量:该模块定义的是真正的标量值,不受上下文切换影响#!/usr/bin/perl use strict; use warnings FATAL => 'all'; use feature qw(say); use Readonly; Readonly my $MY_CONSTANT => 42; use JSON::XS; say encode_json { value => $MY_CONSTANT }; my $smth = 'asdf' . $MY_CONSTANT;无论是否参与字符串拼接,输出始终为
{"value":42}。显式强制数字上下文:如果坚持用
use constant,序列化时通过前缀+或0 +强制转为数字# 两种写法任选其一 say encode_json { value => +MY_CONSTANT }; say encode_json { value => 0 + MY_CONSTANT };使用
const模块(Perl 5.22+):Perl 5.22及以上版本支持的编译时常量,行为更接近真正的常量,不受上下文影响#!/usr/bin/perl use strict; use warnings FATAL => 'all'; use feature qw(say); use const MY_CONSTANT => 42; use JSON::XS; say encode_json { value => MY_CONSTANT }; my $smth = 'asdf' . MY_CONSTANT;
内容的提问来源于stack exchange,提问作者bessarabov
相关产品推荐
相关产品推荐

