免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 14746 | 回复: 6
打印 上一主题 下一主题

关于perl当中字符串转换成数字的疑问 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-11-25 15:23 |只看该作者 |倒序浏览
刚刚开始学习perl,感觉perl语言中遇到操作符时字符串转化成数字太灵活了,所以产生了疑问,请帮忙

举例:
case 1
#############################
use strict;
use 5.10.1;
use feature qw(say);

my $var = "12";
$var + 0;

if ( $var ~~ '12.0' ) {
        say "matched";
} else {
        say "not matched";
}
#############################
结果是matched,因为$var + 0 将其有字符串转化成了数字,并且perl自动将此结果保存给变量 var

case 2
#############################
use strict;
use 5.10.1;
use feature qw(say);

my $var = "12a";
$var + 0;
print "$var\t";

if ( $var ~~ '12.0' ) {
        say "matched";
} else {
        say "not matched";
}
#############################
这次结果是12a    not matched,说明12a没有被转换成数字。

case 3
#############################
use strict;
use 5.10.1;
use feature qw(say);

my $var = "12a" + 0;
#$var + 0;
print "$var\t";

if ( $var ~~ '12.0' ) {
        say "matched";
} else {
        say "not matched";
}
#############################
这次结果是12    matched,说明12a被转换成了数字12


问题出来了,为什么第二种情况perl 不会将其转换成数字12? 然后保存这个值再去和‘12.0’ 进行比较?
能说明情况二和情况一,三的区别吗?

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
2 [报告]
发表于 2011-11-25 16:44 |只看该作者
这里用到了 smart match 的这两个规则

   Num     numish numeric equality       $a == $b
    Any     Any       string equality          $a eq $b


一个字符串如果进行了数学运算会保存起相应的数字值,如果它是个合法的数字则值会被标记为可以用为数字,在 smart match 这里只检测可用的类型。

Scalar::Util::dualvar 这个函数可以让一个值同时可以用为数字和字符串,而且不需要有任何关系,你可以试下

$a = dualvar 33, 'abc';
$a ~~ 33; $a ~~ /abc/ 都为真。以往 Perl 都是通过操作符来选择使用哪种类型的,而 smart match 作为后来者逻辑上的确有瑕疵

论坛徽章:
0
3 [报告]
发表于 2011-11-25 17:16 |只看该作者
谢谢,我明白问题出在了智能匹配上面。

perl的标量类型有字符串和数字两种,什么时候是字符串还是数字?这是由语句的上下文区分的。perl有字符串上下文,也有数字上下文,取决于出现的操作符。
+ ,- ,* ,/ ,== ,>= 这些都是数字操作符,因而期望前后出现数字上下文;
eq,gt,.,lt 这些都是字符串操作符,因而期望出现字符串上下文。
而智能匹配~~ 比较奇特,他会根据左右出现的上下文再去决定是数字上下文还是字符串上下问,这就使得问题有些时候更加奇特乃以理解了。

我的问题,我个人的理解如下:
####################
case 1
####################
my $var = "12";            #var是字符串变量
$var + 0;                      #var转换中字符串成了数字12
if ( $var ~~ '12.0' ) {    #这个时候智能匹配选择数字上下文 12 == 12, TRUE
####################
case 2
####################
my $var = "12a";          #var是字符串变量
$var + 0;                      #var转换中字符串成了数字12
if ( $var ~~ '12.0' ) {    #这个时候智能匹配选择字符串上下文 12 eq 12.0, FALSE
####################
case 3
####################
my $var = "12a" + 0;   #var是数字变量12

if ( $var ~~ '12.0' ) {    #这个时候智能匹配选择数字上下文 12 == 12.0, TRUE
####################


劳烦版主,帮助检查,谢谢!

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
4 [报告]
发表于 2011-11-25 17:34 |只看该作者
回复 3# perlming


>>my $var = "12a";          #var是字符串变量
>>$var + 0;                      #var转换中字符串成了数字12
>>if ( $var ~~ '12.0' ) {    #这个时候智能匹配选择字符串上下文 12 eq 12.0, FALSE

你理解错了.....
$var + 0  #并不会改变$var 内容(还是"12a")

12a    not matched   #"12a" eq "12.0" 当然不会成功...

论坛徽章:
0
5 [报告]
发表于 2011-11-25 18:10 |只看该作者
多谢,刚刚注意到了,呵呵。

引入了我的另外两个新问题
1)如何判断智能匹配语法上下文 是数字上下文还是字符串上下文呢?
我个人觉得最容易理解case 3
####################
my $var = "12a" + 0;   #var是数字变量12
if ( $var ~~ '12.0' ) {    #这个时候智能匹配选择数字上下文 12 == 12.0,转换‘12.0’到数字12

case 1
####################
my $var = "12";            #var是字符串变量
$var + 0;                      #var转换中字符串成了数字12, var有了两种属性(我简称它为属性),数字12和字符串‘12’
if ( $var ~~ '12.0' ) {    #这个时候智能匹配选择数字上下文 12 == 12,??奇怪了为什么选择数字上下文而不是字符串上下文 ‘12’ eq ‘12.0’呢??

case 2
####################
my $var = "12a";          #var是字符串变量
$var + 0;                      #var转换中字符串成了数字12,var有了两种属性,数字12和字符串‘12a’
if ( $var ~~ '12.0' ) {    #这个时候智能匹配选择字符串上下文 ‘12a’ eq ‘12.0’, ??奇怪为什么不选择数字上下文了呢??

2)另外我还有一个困惑的问题就是版主提出的dualvar,这个变量到底存储的是数字变量还是字符串变量,还是都存储然后根据上下文情景再去选择?
我写了一个测试代码如下:
#######################
use Devel:eek qw(Dump);
use Scalar::Util qw(dualvar);
use strict;

my $var1 = 34;
my $var2 = "dbc";
my $var3 = dualvar 34,'dbc';
my $var4 = "34dbc";
Dump($var1);
Dump($var2);
Dump($var3);
$var4 + 0;
Dump($var4);
#######################
结果为
SV = IV(0x182afd0) at 0x182afd4
  REFCNT = 1
  FLAGS = (PADMY,IOK,pIOK)
  IV = 34  <=== 100%数字变量
SV = PV(0x287044) at 0x182b084
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x28f8cc "dbc"\0  <====100%字符串变量
  CUR = 3
  LEN = 4
SV = PVNV(0x288a6c) at 0x182b004
  REFCNT = 1
  FLAGS = (PADMY,IOK,POK,pIOK,pPOK)
  IV = 34      ??50%数字变量??
  NV = 0
  PV = 0x186b05c "dbc"\0    ??50%字符串变量??
  CUR = 3
  LEN = 4
Argument "34dbc" isn't numeric in addition (+) at test.pl line 12.
SV = PVNV(0x288a54) at 0x182b034
  REFCNT = 1
  FLAGS = (PADMY,POK,pIOK,pNOK,pPOK)
  IV = 34
  NV = 34  <===这里和变量三又不太一样
  PV = 0x1824b8c "34dbc"\0
  CUR = 5
  LEN = 8
######################
注意到其中的PV,IV,NV字段有些不同,可以帮我理解吗?谢谢

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
6 [报告]
发表于 2011-11-25 18:40 |只看该作者
多谢,刚刚注意到了,呵呵。

引入了我的另外两个新问题
1)如何判断智能匹配语法上下文 是数字上下文还 ...
perlming 发表于 2011-11-25 18:10



    一个 scalar 可以有 整数、浮点数、字符串几个槽,所以它可以同时是这几种类型,这取决于 IOK NOK POK 这几个标志位。遇到你第二个例子必然要由实现决定是选 Num     numish 还是  Any     Any,当然也可能全都进行

论坛徽章:
0
7 [报告]
发表于 2011-11-28 09:19 |只看该作者
谢谢,周末没上网,刚刚看到。一口气吃不了个胖子,多看多练,慢慢体味吧。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP