24

::Perl和Perl之间的确切区别是什么->

->有时在::不工作的地方工作。

4

3 回答 3

55

::有两个用途。

  1. 它是包名中的命名空间分隔符

    use Foo::Bar;    # Load Foo/Bar.pm
    $Foo::Bar::var   # $var in namespace Foo::Bar
    
  2. 附加到一个裸词,它创建一个字符串文字[1]

    以下是相同的,'hello'只是它在包hello不存在时发出警告:

    hello::
    

->有两个用途。

  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()

前者是函数调用。后者是方法调用。方法调用类似于函数调用,但有两点不同:

  1. 方法调用使用继承。

  2. 方法调用将调用者(剩下的->)作为第一个参数传递给 sub。

{
   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如果subFoo存在,则欺骗性地调用它(使用它返回的值作为调用者)。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');

这意味着->通常在实例方法中使用,以便将对象传递其自身和构造函数,以便构造函数知道要祝福哪个包。这通常是一个参数,因此它可以被继承。

于 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 回答