我是Perl初学者。我不明白为什么我们在perl中使用context(scalar,list,void)
。
请用简单的例子澄清我的疑问。
答案 0 :(得分:3)
数组是列表上下文中包含的值的列表,而标量上下文中包含的值的数量。在void上下文中,它的值被丢弃了。
$, = ' '; # printed fields will be delimited by spaces
my @arr = qw/a b c d/;
@arr; # nothing done (thrown away) in void context
print @arr, "\n"; # function arguments are evaluated in list context by default
print scalar(@arr), "\n"; # scalar() forces scalar context
“默认情况下”是指子程序原型。请参阅perlsub手册页(man perlsub
)。
输出:
a b c d
4
Void上下文并不是真正有趣的IMO。它正在抛弃价值。如果调用子例程返回值而不捕获该值(例如在变量中),则在void上下文中调用它。 请注意,隐式返回看起来不是捕获值,但在这种情况下,上下文是从调用者继承的。
sub x {
return 42;
}
x(); # evaluated in void context
有人认为有趣的是,即使子程序返回某些内容,也不会产生任何错误。只有在启用警告时,在void上下文中使用常量或变量才会生成警告。
在子程序中,可以使用wantarray
确定调用者的上下文。它为void上下文返回undef
,对于列表上下文返回true,对标量上下文返回false。返回参数中的表达式在此上下文中进行评估。
sub print_context {
my $context = wantarray;
unless (defined $context) {
print "void\n";
} elsif ($context) {
print "list\n";
} else {
print "scalar\n";
}
return ''; # empty string
}
print_context(); # void
scalar(print_context()); # scalar
(print_context()); # void
print print_context(); # list
print (print_context()); # list
print +(print_context(), print_context()); # list twice
print scalar(print_context(), print_context()); # void, scalar (comma operator throws away its left operand’s value)
print scalar(+(print_context(), print_context())); # void, scalar (same as above)
print scalar(@{[print_context(), print_context()]}); # list twice, 2 once (array of two empty strings)
我必须承认scalar(print_context());
让我感到惊讶。我期待无效。
可以找到越来越复杂的人工实例。
需要注意哪些背景来自几个实际问题:
scalar()
或使用其中一个期望标量的运算符来确定数组大小)=~
,,
,<>
又名readline
,localtime
,reverse
,each
,caller
,...;以及使用wantarray
自然定义的用户定义man perldata
)中进行了解释。=
)确定用于评估正确运算符的上下文。赋值运算符的行为取决于左操作数的类型。man perlsub
)。return
’s参数中的表达式是在从调用者继承的上下文中计算的。man perlop
)。