在Perl中,::
和->
有什么确切的区别?
->
有时可以起到::
无法实现的作用。
::
有两种用法。
这是包名中的命名空间分隔符
use Foo::Bar; # 加载 Foo/Bar.pm
$Foo::Bar::var # 命名空间 Foo::Bar 中的 $var
附加到裸字上,它会创建一个字符串字面量[1]。
以下代码与 'hello'
相同,但如果包 hello
不存在,则会发出警告:
hello::
->
有两种用法。
它用于解引用。
$array_ref->[$i]
$hash_ref->{$k}
$code_ref->(@args)
它用于方法调用中表示调用者。
CGI->new() # 静态方法调用
$cgi->param() # 对象方法调用
Foo::Bar::mysub()
并且
Foo::Bar->mysub()
{
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);
注意事项
Foo->method
欺骗性地调用名为 Foo
的子程序(使用其返回值作为调用者)。Foo::->method
,即 'Foo'->method
,则不会。更多信息请参考这里。Foo::Bar->f()
会将隐式参数 'Foo::Bar'
传递给 $_[0]
,而 Foo::Bar::f()
则不会。 - el.pescado - нет войне->
后面的部分)作为其第一个参数传递给子程序。”),并得到了证明。 - ikegami->
将其左侧传递为函数的第一个参数。如果 $foo
是一个被绑定到 Foo 包的对象,并且 Bar 在 Foo 包中,则以下示例是等效的。->
将解析继承的方法,使其更加简洁和有用于对象。$foo->Bar();
Foo::Bar($foo);
->
也可以接受一个包名
Foo->Bar();
Foo::Bar('Foo');
->
通常用于实例方法,以便对象被传递给自己和构造函数,以便构造函数知道要赋予哪个包。这通常是一个参数,因此它可以被继承。这里有很多解释,但对于新开发人员来说,以下是非常简单的答案:
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
//
在 Perl 中不是注释符号。使用时应该写成 use FOO
,而不是 using FOO
。 - TLPPerl
而不是 Java
。 - jkshah
A::foo->()
,这会导致歧义,因为无法确定是要调用A包中的foo函数并解除引用结果,还是引用B包中的foo函数。这种歧义可能会导致程序错误或运行不正常。 - fenway