13

ourこのプログラムを書く前は、それはパッケージスコープ変数でmyあり、ファイルスコープ変数だと思っていましたが、そのプログラムを実行した後、混乱しました。

私のプログラムは、

#!/usr/bin/perl

use strict;
use warnings;

package one; 
our $val = "sat";
my $new = "hello";
print "ONE:val =>$val \n";
print "ONE:new =>$new \n\n";

package two;
print "TWO:val =>$val \n";
print "TWO:new =>$new \n";

どの出力

ONE:val =>sat 
ONE:new =>hello 

TWO:val =>sat 
TWO:new =>hello 

myでは、との違いは何ourですか。両方が同じであるか、違いがあるのでしょうか。

4

3 に答える 3

20

ご覧のとおり、とは両方ともmy字句our効果があります。

my字句スコープの変数を作成します。

ourパッケージ変数への字句スコープのエイリアスを作成します。

package語彙のスコープを変更しないと言ったからといって、ステートメントを見た後でも$val、あなたはまだエイリアスです。$one::valpackage two

近いカーリーが表示されない場合は、スコープを終了していません。(またはEOFまたは文字列内の文字列の終わりeval)。

于 2012-05-23T12:38:19.253 に答える
6

変数が宣言された最も内側のブロックへのアクセスを制限します。ブロックがない場合は、ファイルスコープが適用されます。

代わりに、単純な名前を現在のパッケージのパッケージ変数に関連付けるため、パッケージレベルで宣言され、パッケージ名にリンクされます。パッケージ名を追加せずにパッケージ変数を使用できるようにすることで、支援を試みます

package pack;
our $variable;    # These are the same
$pack::variable;  # These are the same

our変数は、Cの静的変数に似ていますが、関数内でourで宣言された変数は、変数の完全修飾名で呼び出された場合でも、関数の外部からアクセスできるため、異なります。

しかし、ほとんどすべての私のスコープは字句スコープですが、私たちは字句スコープですが、宣言ブロックの外でもそれらの寿命は持続します(それらの寿命はグローバル変数の寿命のようなものです)。したがって、私たちの違いを本当に理解するには、字句の違いを理解する必要がありますPerlでグローバルスコープされています。

簡単に言うと、2つのタイプの違いは次のとおりです。

グローバル変数

どのコードでも、どこでも値を変更できます。

字句変数

変数の有効期間は、コードブロックの終わりとともに含まれ、その後、値はガベージコレクションされます。これらの種類の変数には、それらが宣言されているブロック内でのみアクセスできます。


特定の例に答えるには-質問: 2番目のパッケージ宣言(パッケージ2)を別のファイルに移動してみてください。そうすれば 、私私たちの違いがわかります...

于 2012-05-23T12:31:57.480 に答える
3

可視性寿命を区別することが重要です。

またはを使用して宣言された変数の可視性は同一です。この名前は、宣言の後、最初の囲み中括弧またはファイルの終わりの前のどこでも使用できます。ourmy

これは、宣言を必要とせず、どこからでもアクセスできる完全修飾変数名には適用されないことに注意してください。何も宣言せずにパッケージ変数に割り当てることができます

$pack::three = 3;

それをパッケージ内の他の場所で使用します。packパッケージを宣言する必要すらありません。しかし、私が書くなら

package pack;
our $three;

同じ場所で変数を使用できるのと同じ字句スコープ内で使用できる短縮エイリアスを生成しました。囲み中括弧またはファイルの終わりの前です。$pack::threemy

これらのパッケージ変数は、プログラムの実行開始から常に使用可能です。ハッシュ要素と同じように、いつでも新しい要素に割り当てることができ、それは常にそこにあります-それらの寿命は無限です。実際、パッケージ変数すべての意図と目的に対するハッシュ要素です。

一方、で宣言された字句変数は、宣言myの時点で作成され、スコープ外になり、どこにも保持されている参照がなくなると破棄されます。したがって、そのような変数を参照しない限り、その存続期間はその可視性と同じです。ループ内のmy宣言により、ループの実行ごとに新しい変数が作成および破棄されます。

$valコードでは、パッケージ変数$one::valと字句変数のエイリアスを作成しました$new。どちらもコードブロック内にないため、ファイルの最後に両方が表示されます。ここpackage twoではまったく効果がありませんが、2番目のパッケージステートメントのour $val に記述した場合は、代わりにエイリアス$valを変更して示し$two::valます。

それがお役に立てば幸いです。

于 2012-05-23T13:10:44.917 に答える