在Perl中可以使用同名的散列、数组、标量吗?

qyzbxkaa  于 2022-11-15  发布在  Perl
关注(0)|答案(2)|浏览(170)

我正在转换perl脚本到python。
我还没有使用过perl语言之前,perl中的很多东西都让我感到困惑。
例如,在下面,opt首先声明为标量,但再次声明为散列。%opt = ();
在perl中可以用相同的名称声明标量和散列吗?
据我所知,foreach $opt (@opts)意味着标量opt一个接一个地获取数组opt的值。
opt此时是一个数组???
另外,$opt{$opt}是什么意思?

$opt{$opt}之外的选项是散列,而$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;
}
pwuypxnk

pwuypxnk1#

在Perl中,typesSCALARARRAYHASH通过变量名中的前导符号来区分,分别是$@%,但它们可能具有相同的名称。因此,$var@var%var除了属于相同的*var类型团之外,完全不同的变量。
散列的键必须是标量,我们称之为$key。散列中的值也必须是标量,在散列%h中对应于$key的值是$h{$key},前导的$表示它现在是标量。就像数组中的元素是标量,因此是$ary[$index]
foreach $var (@ary)中,标量$var并没有真正“获取”数组元素的值,而是取了它们的别名。因此,如果你在循环中改变它,你就改变了数组的元素。
(Note,您得到的数组是@opts,而不是@opt。)
根据现代Perl中的常见做法,对代码进行一些注解

  • 一个必须始终将use warnings;放在最上面,另一个必须是use strict,因为它强制使用my(或our)声明变量,从而促进所有良好的行为。这将词法(my)变量的作用域限制为包含声明的最近的块
  • 声明也可以在循环内完成,允许while (my $var = EXPR) {}foreach my $var (LIST) {},然后$var的作用域是循环的块(也可以在条件的其余部分使用)
  • local完全是另一种野兽,在这段代码中应该是my
  • arg:这样的循环标签通常用大写字母键入
  • 函数名前面的&有着特殊的含义†,很少用到。
  • 声明变量(使用my)时,不需要分配空列表(如my @optArgs = ()),并且不会产生任何影响(使用全局@name时,可能需要将其从更高的作用域中清除)
  • 在这段代码中,没有必要首先引入变量,因为它们是全局变量,因此在第一次使用它们时就创建了变量,就像Python中的- * 除非它们是在这个sub* 之外使用的,在这种情况下,它们可能需要被清除。这就是全局变量的特点,它们在所有代码中传播

对于此脚本,除了最后两个之外,这些都与Python转换任务无关。
†它抑制原型;通知解释器(在运行时)它是一个子例程,而不是“bareword",如果它还没有被定义的话(可以在名称后加上());如果存在同名的内置函数,则确保调用用户定义的sub;传递调用方的@_(如果没有括号,则为&name);在goto &namedefined中...
例如,请参见this postthis post

hkmswyz6

hkmswyz62#

首先,为了清楚起见,在perl中,就像在shell中一样,您可以用大括号{}将变量名括起来:${bimbo}$bimbo是相同的标量变量。
@bimbo是数组指针; %bimbo是散列指针; $bimbo是标量(唯一值)。
要寻址一个数组或哈希值,您必须使用'$':$bimbo{'index'}是散列值%bimbo的“索引”值。如果$i包含int,例如1,则$bimbo[$i]是数组@bimbo的第二个值。
因此,正如您所看到的,@或% ALWAYS指的是整个数组,而$bimbo{}$bimbo[]指的是散列或数组中的任何值。
${bimbo[4]}为数组@bimbo的第5个值; %{bimbo{'index'}}引用数组%bimbo的“索引”值。
是的,所有这些结构都可以有相同的名称。这是Perl的一个明显的语法。
而且,嗯......总是认为Perl是一个C++的语法,它是简化的,但它是C。

相关问题