问题描述
|
我有一个接受用户输入的功能。输入可以是整数,浮点数或字符串。我有三个重载函数,应根据输入数据的数据类型来调用。例如,如果用户输入一个整数(例如100),则应调用具有整数参数的函数。如果用户输入字符串(例如\“ 100 \”),则应调用具有字符串参数的函数。
所以我需要找出输入数据的数据类型。使用正则表达式,我可以区分整数和浮点数(因为我只需要查找类型,所以我不喜欢使用cpan.org提供的库),但是我不知道如何区分字符串中的整数。 Perl将\“ 100 \”和100视为相同吗?有什么办法可以解决此问题?
解决方法
从
perldoc perldata
:
标量不一定是一回事。没有地方可以将标量变量声明为\“ string \”类型,\“ number \”类型,\“ reference \”类型或其他任何类型。由于标量是自动转换的,因此返回标量的操作不需要关心(实际上也不需要关心)其调用者是在寻找字符串,数字还是引用。 Perl是上下文多态的语言,其标量可以是字符串,数字或引用(包括对象)。尽管对于几乎所有目的,字符串和数字几乎都是同一件事,但是引用是具有内置引用计数和析构函数调用的强类型,不可广播的指针。
因此,对于整数标量,您只需要提前决定如何处理它们即可。 Perl会根据上下文从数字转换为字符串,反之亦然。
, Perl没有在数字和这些数字的字符串表示之间进行有用的区分。您的脚本也不应该。您可以编写一些代码来区分看起来像整数和浮点数的东西,但是知道它是否是字符串的唯一方法是标量看起来像不是整数或浮点数。
这是一个简单的例程,将为其参数返回int
,rat
或str
。注意100
和\'100\'
都是int
,但是类似but7 but的东西就是str
。
use Scalar::Util \'looks_like_number\';
sub guess_type {
looks_like_number($_[0]) ? $_[0] =~ /\\D/ ? \'rat\' : \'int\' : \'str\'
}
say guess_type 1; # int
say guess_type \"1\"; # int
say guess_type 1.1; # rat
say guess_type \'asdf\'; # str
由于您正在将Perl变量映射到C函数,因此可以编写如下代码:
sub myfunction {
if (looks_like_number($_[0]) {
if ($_[0] =~ /\\D/) {C_float($_[0])}
else { C_int($_[0])}
}
else {C_string($_[0])}
}
当给定Perl标量时,哪个应该“做正确的事”。您可能还需要添加检查以查看参数是否为引用,然后以不同方式处理该情况。
, #!perl6
use v6;
multi guess ( Int $a ) { say \"got integer: $a\" }
multi guess ( Str $a ) { say \"got string: $a\" }
multi guess ( Rat $a ) { say \"got float: $a\" }
guess(3);
guess(\"3\");
guess(3.0);
作弊,我知道...
保罗
, 您是否考虑过将带有键的哈希引用传递给该函数,以指示输入是什么数据类型?
my $str_input = { string => \"100\" };
my $int_input = { integer => 100 };
my $float_input = { float => 100.0 };
您可以通过检查输入具有哪个键来检查获得的类型:
my $datatype = shift (keys %{$input})
,然后从那里拿走。 (请注意发生在$input
上的隐式取消引用)
switch ($datatype) {
case string:
C_string($input->{$datatype});
case integer:
C_integer($input->{$datatype});
case float:
C_float($input->{$datatype});
}