我在Perl中有以下程序:
use Class::Struct;
use constant {
ACTION => "Action",
TYPE => "Type"
};
struct MyClass => {
&ACTION => '$',
&TYPE => '$'
};
my $obj = new MyObj{
&ACTION => 'add',
&TYPE => '1'
}
# compilation error:
var $action = $obj->&ACTION;
尝试使用常量访问对象字段时出现编译错误。可能吗?我做错了什么?
答案 0 :(得分:6)
您的代码包含一些错误,例如当您声明的所有内容MyObj
并使用MyClass
而不是var
时尝试实例化my
。修复后,您会注意->&
是语法错误。请参阅Method Invocation和Method Call Variations。
您可以使用
那就是说,这是你的代码,带有更正,使其能够编译和运行:
use strict;
use warnings;
use Class::Struct;
use constant {
ACTION => "Action",
TYPE => "Type"
};
struct MyClass => {
ACTION() => '$',
TYPE() => '$'
};
my $obj = MyClass->new(
ACTION() => 'add',
TYPE() => '1'
);
print $obj->${ \ACTION };
请注意,在声明中使用ACTION()
而不是&ACTION
会将键转换为编译时间常量而不是运行时子例程调用(前缀为ACTION
&
告诉{{ 1}}忽略空原型,有效地撤消perl
)的好处。
引用方法调用
Perl还允许您在方法调用中使用解除引用的标量引用。这是一个满口的,所以让我们看看一些代码:
use constant
上面的代码编译为 $file->${ \'save' };
$file->${ returns_scalar_ref() };
$file->${ \( returns_scalar() ) };
$file->${ returns_ref_to_sub_ref() };
。
像往常一样,@ikegami发现了我错过的内容:$obj->${ \'Action' }
是一个运行时错误。通过使用常量作为方法名称,可以在编译时检测拼写错误。例如,如果我犯了诸如$x->doesnotexist
之类的错误,编译就会失败。
在这种情况下,Const::Fast可能会提供一个美学上更令人愉悦的解决方案(即使它相对于使用常量子例程会有速度惩罚):
$obj->${ \ACITON };
输出:
C:\...\Temp> perl -c tt.pl Global symbol "$ACION" requires explicit package name (did you forget to declare "my $ACION"?) at tt.pl line 21. tt.pl had compilation errors.
也就是说,在编译时也会检测到这样的拼写错误。使用常量子程序会对性能造成损失,但它不那么难看。