Perl 中的标量和列表上下文有什么区别,这在其他语言(如 Java 或 Javascript)中是否有任何相似之处?
3 回答
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;
我所知道的其他语言中的列表和标量上下文没有直接的平行关系。
标量上下文是您在寻找单个值时得到的。列表上下文是您在寻找多个值时得到的。最常见的区别之一是使用数组时:
@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”(预期的真/假值)上下文。
这仅仅意味着将根据操作模式评估数据类型。例如,对标量的赋值意味着右侧将被评估为标量。
我认为理解上下文的最好方法是学习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 @_
}
这篇文章中的示例就像通过将右侧作为参数传递来调用上述子例程一样。
至于其他语言的相似之处,是的,我仍然认为几乎每种语言都支持类似的东西。多态性在所有 OO 语言中都是相似的。另一个例子,Java 在某些上下文中将对象转换为字符串。我用过的每一种无类型脚本语言都有类似的概念。