Perl中的标量和列表上下文之间有什么区别?

时间:2008-12-18 04:38:47

标签: perl list scalar

Perl中的标量和列表上下文之间的区别是什么?它在Java或Javascript等其他语言中是否有任何并行?

3 个答案:

答案 0 :(得分:11)

Perl中的各种运算符都是上下文敏感的,并且在列表和标量上下文中产生不同的结果。

例如:

my(@array) = (1, 2, 4, 8, 16);
my($first) = @array;
my(@copy1) = @array;
my @copy2  = @array;
my $count  = @array;

print "array: @array\n";
print "first: $first\n";
print "copy1: @copy1\n";
print "copy2: @copy2\n";
print "count: $count\n";

输出:

array: 1 2 4 8 16
first: 1
copy1: 1 2 4 8 16
copy2: 1 2 4 8 16
count: 5

现在:

  • $first包含1(数组的第一个元素),因为my($first)中的括号提供了一个数组上下文,但$first中只有一个值的空格。
  • @copy1@copy2都包含@array
  • 的副本
  • $count包含5,因为它是标量上下文,@array在标量上下文中计算数组中元素的数量。

也可以构建更详细的例子(结果是读者的练习):

my($item1, $item2, @rest) = @array;
my(@copy3, @copy4) = @array, @array;

我所知道的其他语言中的列表和标量上下文没有直接并行。

答案 1 :(得分:4)

标量上下文是您在查找单个值时获得的内容。列表上下文是您在查找多个值时获得的内容。最常见的区别之一是使用数组:

@x = @array;  # copy an array
$x = @array;  # get the number of elements in an array

其他运算符和函数也是上下文敏感的:

$x   = 'abc' =~ /(\w+)/;  # $x = 1
($x) = 'abc' =~ /(\w+)/;  # $x = 'abc'
@x   = localtime();       # (seconds, minutes, hours...)
$x   = localtime();       # 'Thu Dec 18 10:02:17 2008'

运算符(或函数)在给定上下文中的行为取决于运算符。对于事物的行为方式没有一般规则。

您可以使用wantarray函数确定调用上下文,从而使您自己的子例程上下文敏感。您可以使用scalar关键字强制在标量上下文中计算表达式。

除了标量和列表上下文之外,您还会看到文档中提到的“void”(没有预期的返回值)和“boolean”(期望的真/假值)上下文。

答案 2 :(得分:0)

这仅表示将根据操作模式评估数据类型。例如,对标量的赋值意味着右侧将被评估为标量。

我认为理解背景的最佳方法是学习关于wantarray。所以假设=是一个实现wantarray的子​​例程:

sub = {
  return if ( ! defined wantarray ); # void: just return (doesn't make sense for =)
  return @_ if ( wantarray ); # list: return the array
  return $#_ + 1; # scalar: return the count of the @_
}

this post中的示例就像通过将右侧作为参数传递来调用上面的子例程一样。

至于其他语言的相似之处,是的,我仍然认为几乎每种语言都支持类似的东西。多态性在所有OO语言中都是类似的。另一个例子,Java在某些上下文中将对象转换为String。我使用的每种无类型脚本语言都有类似的概念。

相关问题