Perl中的->和::有什么区别

g6ll5ycj  于 2023-10-24  发布在  Perl
关注(0)|答案(3)|浏览(193)

Perl中::->的区别是什么?
->有时可以在::不能的地方工作。

w1e3prcc

w1e3prcc1#

::有两个用途。
1.它是包名中的命名空间分隔符

use Foo::Bar;    # Load Foo/Bar.pm
 $Foo::Bar::var   # $var in namespace Foo::Bar

1.将其转换为bareword,它将创建一个字符串字面量[1]。
下面的代码与'hello'相同,除了它在包hello不存在时发出警告:

hello::

->有两个用途。
1.它用于解引用。

$array_ref->[$i]
 $hash_ref->{$k}
 $code_ref->(@args)

1.它在方法调用中用来表示调用方。

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

你可能会问

Foo::Bar::mysub()

Foo::Bar->mysub()

前者是函数调用,后者是方法调用,方法调用与函数调用类似,但有两点不同:
1.方法调用使用继承。
1.方法调用将invocant(->的剩余部分)作为第一个参数传递给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欺骗性地调用名为Foo的子进程(如果它存在的话)(使用它返回的值作为调用方)。Foo::->method,意思是'Foo'->method,没有。关于here的更多信息。
a0zr77ik

a0zr77ik2#

当右边是一个函数时,->将它的左手端作为第一个参数传递给函数。所以下面的例子是等价的,如果$foo是一个被Foo包祝福的对象,而Bar在Foo包中。->将解析继承的方法,使其更干净,对对象更有用。

$foo->Bar();

Foo::Bar($foo);

->也可以使用包名

Foo->Bar();

Foo::Bar('Foo');

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

wko9yo5t

wko9yo5t3#

这里有很多解释,但对于新开发人员来说,这里有一个非常简单的答案:

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

那么没有任何存储变量的包呢?在许多情况下,可能根本没有区别,但这最终取决于类是如何编写的。最后,它比那更复杂..这不是真正的确切答案,但我相信这是你正在寻找的基于你的问题。
为了避免混淆,我在创建一个对象的时候一般不使用classes/packages的名字。如果因为某些原因我不知道该怎么称呼它,我会在它前面加上一个“o”,这样就可以清楚地表明它是一个对象而不是一个类,这对任何编程语言来说都是一个很好的做法。
即使用

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

希望能帮上忙。

相关问题