perl - 为什么标量sub {(@x,@y)}->()返回标量@y?

标签 perl

我对Perl有一些“了解”:

  • 列出扁平化的
  • 函数获取和返回列表

  • 所以,如果我有这个:
    sub my_test {
      my @x = qw(a b c);
      my @y = qw(x y z t);
      return (@x, @y); 
    } 
    
    say my_test; # a b c x y z t
    say scalar my_test;
    

    我期望两个结果值之一:
  • 7,因为那是列表qw(a b c x y z t)中有多少个项目。确实,这就是我从scalar sub { @{[ qw(a b c x y z t) ]} }->()获得的。
  • 't',因为如果您将逗号解释为逗号运算符(叹气),则会得到('a', 'b', 'c', 'x', 'y', 'z', 't'),其结果为't'。确实,这就是我从scalar sub { qw(a b c x y z t) }->()获得的。

  • 相反,您得到的是……4,没有警告。为什么我混用了列表拼合和逗号运算符?

    类似的故事,带有散列和颇为流行的模式:
    sub default_override_hash {
      my %defaults = (foo => 'bar', egg => 'quuz');
      my %values = @_;
      my %overrides = (__baz => '');
      return (%defaults, %values, %overrides);
    }
    
    scalar default_override_hash; # '1/8'
    
    scalar如何知道default_override_hash返回了三个哈希,它不仅应该获取%overrides(不是所有内容,也不是''),还应该将其标量表示为哈希?

    最佳答案

    最重要的一点是:列表不会变平。 (列表是平坦的,但它们不会展平,因为这样做必须首先嵌套。)

    列表上下文中的,(逗号运算符)是列表串联。列表上下文中的A , B评估列表上下文中的AB,然后合并结果。

    标量上下文中的A , B的工作方式类似于C(或JavaScript):它在void上下文中评估A,然后在标量上下文中评估(并返回)B。 (void上下文中的A , B的工作原理相同,但也可以在void上下文中评估B。)

    return X中,X的上下文是函数调用本身的上下文。因此sub my_test { return X } scalar my_test类似于scalar X就像return动态地查看当前子调用所在的上下文,并相应地评估其操作数表达式。

    perldoc perlsub says:

    A return statement may be used to exit a subroutine, optionally specifying the returned value, which will be evaluated in the appropriate context (list, scalar, or void) depending on the context of the subroutine call.)



    如上所述,标量上下文中的@x, @y在void上下文中评估@x(对于数组不执行任何操作),然后在标量上下文中评估并返回@y。标量上下文中的数组会产生其包含的元素数量。

    同样的逻辑适用于%defaults, %values, %overrides , is left-associative,因此将其解析为(%defaults , %values) , %overrides
    这将在void上下文中评估%defaults , %values(反过来评估%defaults,然后在void上下文中评估%values,这无效),然后在标量上下文中评估并返回%overrides。标量上下文中的哈希返回描述哈希内部的(相当无用的)字符串。

    关于perl - 为什么标量sub {(@x,@y)}->()返回标量@y?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38550244/

    相关文章:

    regex - 如何获取嵌套捕获组中除最后一个匹配项之外的任何匹配项?

    java - 有人可以向我解释线程吗?

    perl - Perl Diamond运算符中的奇怪内容

    php - 如何使用多维数组中的值对多维数组进行排序?

    perl - 更新到 Windows 10 后 Net::SSH2::Simple 失败

    perl - Linux perl 模块管理

    perl - 将 2 行合并为 1

    performance - Perl:写入速度之谜?

    perl - 如何加快我的 Perl 程序?

    Perl:理解负数的模运算(例如 -10%3)