24

Perlの::との正確な違いは何ですか?->

->::機能しない場合もあります。

4

3 に答える 3

55

::2つの用途があります。

  1. パッケージ名の名前空間区切り記号です

    use Foo::Bar;    # Load Foo/Bar.pm
    $Foo::Bar::var   # $var in namespace Foo::Bar
    
  2. ベアワードに追加すると、文字列リテラル[1]が作成されます。

    以下は、パッケージが存在しない'hello'場合に警告することを除いて、 と同じです。hello

    hello::
    

->2つの用途があります。

  1. 逆参照に使用されます。

    $array_ref->[$i]
    $hash_ref->{$k}
    $code_ref->(@args)
    
  2. 呼び出し元を示すためにメソッド呼び出しで使用されます。

    CGI->new()        # Static method call
    $cgi->param()     # Object method call
    

あなたはおそらく違いは何ですかと尋ねているでしょう

Foo::Bar::mysub()

Foo::Bar->mysub()

前者は関数呼び出しです。後者はメソッド呼び出しです。メソッド呼び出しは関数呼び出しに似ていますが、次の 2 つの違いがあります。

  1. メソッド呼び出しは継承を使用します。

  2. ->メソッド呼び出しは、呼び出し元 ( の残り) を最初の引数としてサブルーチンに渡します。

{
   package Foo::Baz;
   sub new {
      my ($class, $arg) = @_;
      my $self = bless({}, $class);
      $self->{arg} = $arg;
      return $self;
   }

   sub mysub1 {
      my ($self) = @_;
      print($self->{arg}, "\n");
   }
}

{
   package Foo::Bar;
   our @ISA = 'Foo::Baz'; 
   sub mysub2 {
      my ($self) = @_;
      print(uc($self->{arg}), "\n");
   }
}

my $o = Foo::Bar->new('hi');  # Same as: my $o = Foo::Baz::new('Foo::Bar', 'hi');
$o->mysub1();                 # Same as: Foo::Baz::mysub1($o);
$o->mysub2();                 # Same as: Foo::Bar::mysub2($o);

ノート

  1. Foo->method名前付きのサブルーチンが存在する場合は、そのサブルーチンを呼び出しますFoo(呼び出し元として返される値を使用します)。Foo::->method、つまり'Foo'->method、しません。
于 2013-10-27T18:38:29.803 に答える
7

右辺が関数の場合、->左辺を最初の引数として関数に渡します。したがって、次の例$fooは、オブジェクトがパッケージ Foo にブレスされ、Bar がパッケージ Foo に含まれている場合と同等です。->継承されたメソッドを解決して、オブジェクトにとってよりクリーンで便利にします。

$foo->Bar();

Foo::Bar($foo);

->パッケージ名を取ることもできます

Foo->Bar();

Foo::Bar('Foo');

これは、->が通常インスタンス メソッドで使用されることを意味し、オブジェクトがそれ自体とコンストラクターに渡されるため、コンストラクターはどのパッケージで bless するかを認識します。これは通常パラメーターであるため、継承できます。

于 2013-10-27T18:34:45.950 に答える
-6

ここには多くの説明がありますが、新しい開発者向けの非常に単純な答えは次のとおりです。

FOO::BAR();  # is calling the class's (aka. package's) default object
$FOO->BAR(); # is calling an initiated object

通常、オブジェクトには頻繁に設定されるプロパティがありますが、初期化されていないオブジェクトはデフォルトのオブジェクト プロパティのみを使用します。

FOO に「Age」というプロパティがあり、デフォルト値が 1 であるとします。これは、プログラムの前半で set コマンドを使用して変更できます。次に、楽しみのためにパッケージを両方の方法で再度呼び出すことにしました。

use FOO;
$FOO = new FOO(); #new instance of foo 
$FOO->SetAge(21);

# more code here

print $FOO->GetAge(); # prints 21
print FOO::GetAge(); # prints 1

保存された変数のないパッケージはどうですか? 多くの場合、違いはまったくないかもしれませんが、これは最終的にクラスの書き方に依存します。結局、それはそれよりも複雑です..これは本当に正確な答えではありませんが、あなたの質問に基づいてあなたが探しているものだと私は信じています.

混乱を避けるために、オブジェクトを作成するときにクラス/パッケージ名を使用しません。なんらかの理由でそれを何と呼ぶべきかわからない場合は、「o」を前に付けて、クラスではなくオブジェクトであることを明確にします。これは、どのプログラミング言語でも良い方法です。

すなわち使用

$oFOO = new FOO(); // new object instance of foo

それが役立つことを願っています。

于 2013-10-27T21:22:05.947 に答える