【发布时间】:2020-08-26 23:16:10
【问题描述】:
我有一个返回数组的函数,我想只从该数组中获取第一项,而无需为数组声明变量。基本上,它应该是这样的:
functionReturningArray()[1]
除非那不起作用。
我真的不想浪费空间来声明整个数组,因为我不需要它,我也不想浪费额外的代码行。无论如何要在一行中做到这一点?
【问题讨论】:
标签: perl
我有一个返回数组的函数,我想只从该数组中获取第一项,而无需为数组声明变量。基本上,它应该是这样的:
functionReturningArray()[1]
除非那不起作用。
我真的不想浪费空间来声明整个数组,因为我不需要它,我也不想浪费额外的代码行。无论如何要在一行中做到这一点?
【问题讨论】:
标签: perl
my $item = (function_returning_list())[0];
函数不能返回数组,它们可以返回数组(即列表)的内容。列表从0 开始索引,因此函数返回的第一项是(func)[0]。你也可以说
my ($item) = function_returning_list();
这会将function_returning_list 置于列表上下文中,并对左侧列表中的变量进行赋值(按顺序)。
需要注意的是
sub function_returning_list {
return ("a", "b", "c")
}
my $item = function_returning_list();
可能不会按照您的预期进行。 $item 变量将被分配"c"。这是因为在标量上下文中没有列表这样的东西。相反,您在标量上下文中使用逗号运算符,它在 void 上下文中计算左侧表达式,丢弃结果,然后在标量上下文中计算右侧。
我称之为序列(而不是列表),如果像 C 风格的 for 循环这样的一些情况,它很有用。
【讨论】:
() 变成undef,所以它只有在列表上下文中才能咬你。如果您不确定您是在标量还是列表上下文中,请务必记住说 scalar((function_returning_list())[0])。
首先,[1] 是列表中的第二项,因为 Perl 使用从 0 开始的索引。
其次,您需要在列表上下文中评估函数的返回值才能访问列表。
(functionReturningArray())[0]
【讨论】:
比 Chas 的回答下面的讨论更进一步,没有列表期这样的东西。
与具有填充此角色的元组类型的 Python 不同,Perl 的列表完全是编译器/解释器中堆栈的构造。这就是为什么不能引用列表的原因。
就像 python 对元组的使用一样,当使用诸如 = 赋值运算符之类的构造时,perl 会自动推送和移动其堆栈以在变量组中移动。 (Perl 的优先规则需要括号,因为= 的绑定比, 更紧密)。 Perl 和 Python 的机制之间的宏观差异是上下文通过整个表达式传播。
因此,在标量上下文中,该上下文被分配给每个 , 运算符,运算符在 void 上下文中执行其左侧,然后在标量上下文中执行其右侧,然后返回。然而,在列表上下文中,, 运算符将其参数推入堆栈,所有这些都在列表上下文中执行。然后堆栈通过赋值运算符传递,然后移入左值。堆栈/列表本身对于 Perl 级别的代码是不可变的,它的修改工具实际上是 Perl 的所有语法。
因此,虽然在标量上下文中引用列表是不正确的(因为这种事情不可能发生),但您可以像语法结构一样引用列表的行为(由, 运算符构造,由数组构造切片或列表切片)。在标量上下文中,类似列表的构造的行为是返回列表的最后一个元素。如何实现这一点取决于表达式中的运算符。这当然与在标量上下文中返回其长度的数组的行为形成对比。
举例说明,最后遵守规则,实际回答问题:
假设my @array = (10, 11, 12);
标量上下文
my $val = (10, 11, 12); # $val is 12
my $val = (10 .. 20)[0 .. 5]; # $val is 15
my $val = @array; # $val is 3
my $val = function(); # $val is the last executed expression
function 以10, 11, 12 结尾,那么值将是12@array,则值为310, 11, 12, @array结尾,则该值也是3
列出上下文
my ($val) = (10, 11, 12); # $val is 10
my ($val) = (10 .. 20)[0 .. 5]; # $val is 10
my ($val) = @array; # $val is 10
my ($val) = function(); # $val is the first executed expression
# in the last statement.
function 以10, 11, 12 结尾,那么值将是10@array,则值为1010, 11, 12, @array结尾,则该值也是10
为了完整起见,列表上下文将整个列表抓取到一个数组中
my @val = (10, 11, 12); # @val is 10, 11, 12
my @val = (10 .. 20)[0 .. 5]; # @val is 10, 11, 12, 13, 14, 15
my @val = @array; # @val is 10, 11, 12
my @val = function(); # @val is the last executed statement
function 以10, 11, 12 结尾,那么@val 将是10、11、12@array,那么 @val 将是 10、11、1210, 11, 12, @array 结尾,那么@val 将是10、11、12、10、11、12【讨论】: