带数组的简单示例
数组是列表上下文中包含的值的列表,而标量上下文中包含的值的数量。在 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
空上下文示例及说明
IMO 的空上下文并不是很有趣。它正在丢弃价值。如果您调用返回值的子例程而不捕获该值(例如在变量中),它将在 void 上下文中调用。 请注意,隐式返回看起来不像捕获值,但在这种情况下,上下文是从调用者继承的。
sub x {
return 42;
}
x(); # evaluated in void context
有趣的是,即使子程序返回了一些东西,这也不会产生错误。只有在启用警告时,在 void 上下文中使用常量或变量才会产生警告。
子程序内的上下文
在子程序中,调用者的上下文可以使用wantarray 来确定。对于 void 上下文,它返回 undef,对于列表上下文返回 true,对于标量上下文返回 false。 return 参数中的表达式在此上下文中计算。
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() 或使用期望标量的运算符之一)
- 解决了在标量上下文中错误地评估数组(因此扩展到其大小)而不是通过强制列表上下文来解决的事故
- 使用在不同上下文中行为不同的运算符和子例程(例如
=~、,、<> aka readline、localtime、reverse、each、caller、...;和那些使用wantarray 的用户定义,自然)
关于上下文的一般和非常深刻的真相