7

以下のコードを参照してください。

$scalar = 10;

subroutine(\$scalar);

sub subroutine {
    my $subroutine_scalar = ${$_[0]}; #note you need the {} brackets, or this doesn't work!
    print "$subroutine_scalar\n";
}

上記のコードでは、「{} ブラケットが必要であることに注意してください。そうしないと機能しません!」というコメントが表示されます。. 以下と同じステートメントを使用できない理由を説明してください。

my $subroutine_scalar = $$_[0];

つまり、中括弧を使用しません。

4

4 に答える 4

9

多くの人がここですでに正しい答えを出しています。わかりやすい例を追加したいと思いました。詳細については、 perldoc perlrefのドキュメントを参照してください。

あなたの問題はあいまいさの1つであり、2つの操作が$$あり[0]、同じ識別子に取り組んで_おり、結果はどちらの操作が最初に実行されるかによって異なります。サポート中かっこを使用することで、あいまいさを軽減できます${ ... }$$_[0](とにかく人間にとって)おそらく次のことを意味します:

  • ${$$_}[0]-- スカラー$_を逆参照し、最初の要素を取得します。
  • ${$_[0]}--0配列の要素を取得@_し、逆参照します。

ご覧のとおり、これら 2 つのケースはまったく異なる変数を参照して@_おり、$_.

もちろん、Perl の場合はあいまいではありません。逆参照はキー ルックアップの前に実行されるため、単純に最初のオプションを取得します。この逆参照をオーバーライドするには、サポート中括弧が必要です。そのため、サポート中括弧なしでは例が「機能」しません。

サブルーチンの混乱を少し軽減する機能を検討することもできます。2 つのことを一度に行う (引数を取得して逆参照する) のではなく、2 段階で行うことができます。

sub foo {
    my $n = shift;
    print $$n;
}

ここでは、最初の引数を@_で取り除きshift、逆参照します。クリーンでシンプル。

ただし、ほとんどの場合、スカラー変数への参照は使用しません。そのような場合、矢印演算子を利用できます->

my @array = (1,2,3);
foo(\@array);

sub foo {
    my $aref = shift;
    print $aref->[0];
}

構文よりも矢印演算子を使用する方が望ましいと思い$$ます。

于 2013-10-18T13:36:18.337 に答える
2
my $subroutine_scalar = $$_[0];

と同じです

my $subroutine_scalar = $_->[0]; # $_ is array reference

一方で、

my $subroutine_scalar = ${$_[0]};

配列の最初の要素のスカラー ref を逆参照し、次の@_ように記述できます。

my ($sref) = @_;
my $subroutine_scalar = ${$sref}; # or $$sref for short
于 2013-10-18T12:26:40.847 に答える
1

なぜなら$$_[0]手段${$_}[0]

両方とも出力する次の 2 つのコードについて考えてみましょう10

sub subroutine1 {
    my $scalar = 10;
    my $ref_scalar = \$scalar;
    my @array = ($ref_scalar);
    my $subroutine_scalar = ${$array[0]};

    print "$subroutine_scalar\n";
}

sub subroutine2 {
    my @array = (10);
    my $ref_array = \@array;
    my $subroutine_scalar = $$ref_array[0]; 

    print "$subroutine_scalar\n";
}

ではsubroutine1@arrayの参照を含む配列です$scalar。したがって、最初のステップは、 によって最初の要素を取得し、$array[0]それを参照することです。

while insubroutine2@arrayスカラーを含む配列10で、 $ref_array はその参照です。したがって、最初のステップは、 で配列を取得してから、配列$ref_arrayにインデックスを付けることです。

于 2013-10-18T12:13:40.570 に答える