【问题标题】:Finding the data type of a scalar variable in Perl在 Perl 中查找标量变量的数据类型
【发布时间】:2011-06-15 17:23:38
【问题描述】:

我有一个接受用户输入的函数。输入可能是整数、浮点数或字符串。我有三个重载函数,应该根据输入数据的 DATA TYPE 调用它们。例如,如果用户输入一个整数(比如 100),则应调用具有整数参数的函数。如果用户输入一个字符串(比如“100”),则应该调用具有字符串参数的函数。

所以我需要找出输入数据的数据类型。使用正则表达式,我能够区分整数和浮点数(因为我只需要找出类型,我不喜欢使用 cpan.org 提供的库),但我无法弄清楚如何区分字符串中的整数。 Perl 将“100”和 100 视为相同?有没有办法解决这个问题?

【问题讨论】:

  • 处理"100"100 通常被认为是Perl 的一个特性。您需要更好地解释为什么这是一个问题。当用户调用your_function(100) 时会发生什么,与用户调用your_function("100") 时应该有什么不同?
  • 哦.. 我想不深入这个细节。但是由于情况需要:我必须从 perl 内部调用一些 C 函数。这些函数被重载并出现在我的库中。所以我需要找出类型并明确调用函数的正确版本。
  • 忽略我的[已删除]答案。我误解了问题的意图,并没有意识到您所说的“输入”是函数的物理参数。
  • 如果用户调用 my_function(100),函数应该调用一些 C_int(100) 而如果用户调用 my_function("100"),函数应该调用,比如 C_string("100" )

标签: perl


【解决方案1】:

来自perldoc perldata

标量不一定是一回事。没有地方可以将标量变量声明为“string”类型、“number”类型、“reference”类型或其他任何类型。由于标量的自动转换,返回标量的操作不需要关心(事实上,也不关心)调用者是在寻找字符串、数字还是引用。 Perl 是一种上下文多态语言,其标量可以是字符串、数字或引用(包括对象)。尽管字符串和数字在几乎所有用途中都被视为几乎相同的东西,但引用是强类型的、不可转换的指针,具有内置的引用计数和析构函数调用。

因此,对于整数标量,您只需提前决定要如何处理它们。 Perl 会根据上下文愉快地将数字转换为字符串,反之亦然。

【讨论】:

  • 嗯,谢谢.. 所以我不应该在这件事上浪费我的时间,而是想出一些其他的方法来处理它.. :D
【解决方案2】:

Perl 没有在数字和这些数字的字符串表示之间做出有用的区分。你的脚本也不应该。您可以编写一些代码来区分看起来像整数和浮点数的东西,但知道它是否是字符串的唯一方法是标量看起来不像整数或浮点数。

这是一个简单的例程,它将为其参数返回 intratstr。请注意100'100' 都是int,但'asdf' 之类的将是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 标量时,应该“做正确的事”。您可能还想添加检查以查看参数是否为引用,然后以不同的方式处理这种情况。

【讨论】:

  • 我完全不同意这一点:“你的脚本也不应该。”仅仅因为一种语言不做某事并不意味着做那件事总是错误的。
【解决方案3】:
#!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);

作弊,我知道...

保罗

【讨论】:

  • 听起来不错!!一定会试一试的。有任何机会,任何此类选项或版本 5 的任何其他替代方案??
【解决方案4】:

您是否考虑过向函数传递哈希引用,其中的键指示输入的数据类型?

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});
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-09
    • 2019-12-28
    • 1970-01-01
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多