标量,列表,无效的上下文

时间:2013-12-16 06:37:34

标签: perl user-defined-functions

我是Perl初学者。我不明白为什么我们在perl中使用context(scalar,list,void)

请用简单的例子澄清我的疑问。

1 个答案:

答案 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上下文示例和说明

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()或使用其中一个期望标量的运算符来确定数组大小)
  • 解决在标量上下文中错误评估数组时的事故(因此扩展到其大小)并且不打算强制列表上下文
  • 使用在不同上下文中表现不同的运算符和子例程(例如=~,<>又名readlinelocaltimereverseeachcaller,...;以及使用wantarray自然定义的用户定义

有关上下文的一般和非常深刻的事实

  • 上下文的概念在perldata手册页(man perldata)中进行了解释。
  • 赋值运算符的左操作数(=)确定用于评估正确运算符的上下文。赋值运算符的行为取决于左操作数的类型。
  • 上述子程序原型包括评估其参数的上下文。请参阅perlsub手册页(man perlsub)。
  • return’s参数中的表达式是在从调用者继承的上下文中计算的。
  • Parentheses have nothing to do with context,一般都没有列表上下文和列表。他们总是只是改变优先权。 或者它们围绕着函数调用参数列表,形成一个术语。请参阅perlop手册页(man perlop)。