【问题标题】:Is it possible to use hash, array, scalar with the same name in Perl?是否可以在 Perl 中使用同名的哈希、数组、标量?
【发布时间】:2018-03-01 00:36:54
【问题描述】:

我正在将 perl 脚本转换为 python。
在 perl 中的很多东西让我感到困惑之前,我还没有使用过 perl 语言。
例如,在下面, opt 首先被声明为标量,但再次声明为哈希。 %opt = ();
是否可以在 perl 中声明具有相同名称的标量和哈希?

据我所知,foreach $opt (@opts) 表示标量 opt 一个接一个地获取数组 opts 的值。
此时opt是一个数组???
另外,$opt{$opt}是什么意思?
opt outside $opt{$opt} 是一个散列,而 opt inside $opt{$opt} 是一个标量?
我很困惑,请帮助我......

sub ParseOptions
{
    local (@optval) = @_;
    local ($opt, @opts, %valFollows, @newargs);

    while (@optval) {
        $opt = shift(@optval);
        push(@opts,$opt);
        $valFollows{$opt} = shift(@optval);
    }

    @optArgs = ();
    %opt = ();

    arg: while (defined($arg = shift(@ARGV))) {
        foreach $opt (@opts) {
            if ($arg eq $opt) {
                push(@optArgs, $arg);
                if ($valFollows{$opt}) {
                    if (@ARGV == 0) {
                        &Usage();
                    }
                    $opt{$opt} = shift(@ARGV);
                    push(@optArgs, $opt{$opt});
                } else {
                    $opt{$opt} = 1;
                }
                next arg;
            }
        }
        push(@newargs,$arg);
    }

    @ARGV = @newargs;
}

【问题讨论】:

    标签: perl


    【解决方案1】:

    在 Perl 中,typesSCALARARRAYHASH 分别由变量名中的前导符号 $@% 区分,否则它们可能会承受同名。所以 $var@var%var 除了属于同一个 *var typeglob 之外,是完全不同的变量。

    哈希的键必须是标量,我们称之为$key。散列中的值也必须是标量,散列%h中的$key对应的是$h{$key},前面的$表示现在是标量。就像数组的元素是标量一样,因此$ary[$index]

    foreach $var (@ary) 中,标量$var 并不真正“获取”数组元素的值,而是aliases 它们。所以如果你在循环中改变它,你就会改变数组的元素。

    (注意,你有数组@opts,而不是@opt。)


    根据现代 Perl 中的常见做法,对代码进行一些 cmet

    • 必须始终在顶部有use warnings;。另一个必须的是use strict,因为它强制使用my(或our)声明变量,促进各种良好行为。这将lexical (my) variables 的范围限制为包含声明的最近块

    • 1234563 p>
    • local 完全不同,在这段代码中应该是 my

    • 循环labelsarg: 一样通常用大写字母输入

    • 函数名前面的& 具有相当特殊的含义,很少需要。这段代码几乎肯定不需要它

    • 在声明变量时(使用my)分配像my @optArgs = () 这样的空列表是不需要的并且没有效果(对于全局@name,可能需要将其从更高的范围中清除)

    • 1234563 >,在这种情况下,它们可能需要被清除。全局变量就是这样,它们辐射到所有代码中

    对于此脚本,除了最后两个之外,这些都与您的 Python 翻译任务无关。


     它抑制prototypes;通知解释器(在运行时)它是一个子例程,而不是一个“bareword”,如果它还没有被定义(可以在名字后面加上());如果存在同名的内置函数,则确保调用用户定义的 sub;通过调用者的@_(如果没有括号,&name);在goto &namedefined ...例如,请参见this postthis post

    【讨论】:

      【解决方案2】:

      首先,为了清楚起见,在 perl 中,与在 shell 中一样,您可以将变量名括在大括号 {} 中: ${bimbo}$bimbo 是同一个标量变量。

      @bimbo 是一个数组指针; %bimbo 是一个哈希指针; $bimbo 是一个标量(唯一值)。

      要处理数组或哈希值,您必须使用 '$' : $bimbo{'index'} 是哈希 %bimbo 的“索引”值。 如果 $i 包含一个 int,例如 1, $bimbo[$i] 是数组@bimbo 的第二个值。

      因此,如您所见,@ 或 % 始终指代整个数组,因为 $bimbo{}$bimbo[] 指代散列或数组的任何值。

      ${bimbo[4]}指的是数组@bimbo的第5个值; %{bimbo{'index'}} 指的是数组%bimbo 的'index'值。

      是的,所有这些结构都可以具有相同的名称。这是 perl 的明显语法之一。

      而且,嗯……在 perl 中总是认为是 C++ edulcored 语法,它被简化了,但它是 C。

      【讨论】:

      • @bimbo%bimbo 分别是一个数组和一个散列,而不是任何类型的指针。 \@bimbo\%bimbo 是数组和哈希引用(技术上不是指针,但对于大多数日常使用来说基本上是一样的),其中任何一个都可以分配给 $bimbo_ref
      • 你是对的,在 perl 意义上。但是如果客观评价下的代码,它被认为是一个指针,而不是一个完整的对象
      猜你喜欢
      • 2017-02-09
      • 2019-09-04
      • 2015-03-26
      • 2013-06-23
      • 1970-01-01
      • 1970-01-01
      • 2022-07-06
      • 2011-09-30
      • 1970-01-01
      相关资源
      最近更新 更多