【问题标题】:How do I get the first item from a function that returns an array in Perl?如何从 Perl 中返回数组的函数中获取第一项?
【发布时间】:2020-08-26 23:16:10
【问题描述】:

我有一个返回数组的函数,我想只从该数组中获取第一项,而无需为数组声明变量。基本上,它应该是这样的:

functionReturningArray()[1]

除非那不起作用。

我真的不想浪费空间来声明整个数组,因为我不需要它,我也不想浪费额外的代码行。无论如何要在一行中做到这一点?

【问题讨论】:

    标签: perl


    【解决方案1】:
    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 循环这样的一些情况,它很有用。

    【讨论】:

    • 在标量上下文中没有列表这样的东西。在标量上下文中没有列表这样的东西。在标量上下文中没有列表这样的东西。在标量上下文中没有列表这样的东西。在标量上下文中没有列表这样的东西。在标量上下文中没有列表这样的东西。在标量上下文中没有列表这样的东西。在标量上下文中没有列表这样的东西。
    • 标量上下文中有逗号运算符。见Know the difference between a list and an array
    • @cjm,我想是在您尝试使用它时,它有一个哈希键或值?在标量上下文中() 变成undef,所以它只有在列表上下文中才能咬你。如果您不确定您是在标量还是列表上下文中,请务必记住说 scalar((function_returning_list())[0])
    • 没用。我已经教 Perl 足够长的时间了,我知道说一些完全错误的东西是人们接受和使用的。当你说它时,他们相信它,因为他们并不真正理解它。我们可以进行编辑大战,但你最好使用不是谎言的词,就像我在我指给你的帖子中所做的那样。
    • @Chas:场景在常见问题解答和我发布的链接中。真的,这并不难。在这种情况下没有必要撒谎。
    【解决方案2】:

    首先,[1] 是列表中的第二项,因为 Perl 使用从 0 开始的索引。

    其次,您需要在列表上下文中评估函数的返回值才能访问列表。

    (functionReturningArray())[0]
    

    【讨论】:

      【解决方案3】:

      比 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
        
        • 所以如果function10, 11, 12 结尾,那么值将是12
        • 如果改为@array,则值为3
        • 如果它以10, 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.
        
        • 所以如果function10, 11, 12 结尾,那么值将是10
        • 如果改为@array,则值为10
        • 如果它以10, 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
        
        • 所以如果function10, 11, 12 结尾,那么@val 将是10、11、12
        • 如果是 @array,那么 @val 将是 10、11、12
        • 如果它以10, 11, 12, @array 结尾,那么@val 将是10、11、12、10、11、12

      【讨论】:

      • 不要将语言与其实现混淆。
      • 我看不出准确指出 perl 中的“列表”是什么是令人困惑的,它不像有其他实现......我写的有什么问题吗?跨度>
      猜你喜欢
      • 2017-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多