【问题标题】:In Perl, what is the difference between @array[1] and $array[1]?在 Perl 中,@array[1] 和 $array[1] 有什么区别?
【发布时间】:2011-12-01 05:55:48
【问题描述】:

我一直在研究array slices,坦率地说,我看不出选择@array[1]$array[1] 之间的区别。有区别吗?

#!/usr/bin/perl 
@array = (1,3);
print "\nPrinting out full array..\@array\n";
print "@array\n";
print "\n";
print "Printing out \@array[1]\n";
print "@array[1]\n";
print "Printing out \$array[1]\n";
print "$array[1]\n";
print "\n\n";

【问题讨论】:

    标签: arrays perl


    【解决方案1】:

    This is a FAQ.

    这两种形式可能在许多情况下都以相同的方式工作(但并非全部,正如您从常见问题解答中的示例中看到的那样),但$array[1] 更清楚地表达了意图。

    【讨论】:

      【解决方案2】:

      $@ 被称为印记:听听印记告诉你什么

      当您看到$ 时,您正在处理一件事情。 当您看到 @ 时,您会看到一个列表。

      @array[ 1 ] 是一个切片,一个包含@array 列表中选定元素的列表。你在这个切片中只放了一个元素,@array 的第二个元素,但无论如何它是一个列表。

      $array[ 1 ] 是列表的第二个元素,单个值,一个标量。

      @hash{ 'one', 'two' } 是另一种切片:这次我们切片一个哈希(%hash),得到一个列表,其值对应于键 onetwo

      区别在哪里?尽管差异很小,但当您需要单个值时,应避免使用单个元素切片。请记住,在表达式的右侧,单个元素切片的行为类似于标量,但是当它们位于表达式的左侧时,它们变成了列表赋值:它们为表达式提供了列表上下文。

      如果您仍然对标量上下文和列表上下文之间的区别感到不舒服,请不要使用单元素切片以避免在某些情况下出现意外结果(例如使用行输入运算符 < > 时) .

      检查文档并使用 Perl。

      【讨论】:

      • 另外,use warnings 将通过发出警告(当运行 OP 的代码时)Scalar value @array[1] better written as $array[1] at -e line 7. 来帮助避免使用单元素切片
      【解决方案3】:

      您已经从 Keith 和 Marco 那里得到了答案:@ 表示列表,$ 表示标量(单值)。我还有更多不适合评论的补充。

      您没有注意到差异,因为您使用的是一个元素的切片。但是,试试这个:

      use warnings;
      use strict;
      use v5.10; # to enable say
      
      my @array = (1 .. 10);
      say "@array[2 .. 4]"; # [2,3,4] == "3 4 5"
      say "@array[1,4,7]";  #         == "2 5 8"
      

      这里有一些指向您的代码的指针。

      use strict;
      use warnings;
      

      真的没有理由不使用这两个。几乎没有任何情况下不使用它们会更好或更容易。当您尝试学习 perl 时,尤其如此。

      如果您使用过警告,您将获得以下附加信息:

      Scalar value @array[1] better written as $array[1]
      

      这基本上就是您在这里得到的答案,尽管是用 perl 编译器的简洁语言说的。

      另外,使用print 的方式会让人难以接受。利用 perl 的灵活性:

      #!/usr/bin/perl 
      use strict;
      use warnings;
      
      my @array = (1 .. 10);
      print "
      Printing out full array..\@array
      @array
      
      Printing out \@array[1]
      @array[1]
      Printing out \$array[1]
      $array[1]
      
      
      ";
      

      如您所见,这将以所见即所得的方式打印出换行符。

      【讨论】:

      • @ChrisLutz 问题是“为什么要使用 here-doc?”
      • 因为某种原因,字符串中的文字换行符对我来说看起来不正确?我喜欢在同一行中匹配的引号。
      • @ChrisLutz 我同意,这是一个品味问题。我喜欢这种方式,因为它有一种更原生的 perl 感觉。
      【解决方案4】:

      有两个区别:

      1. 在数组切片 (@foo[1]) 的情况下,«1» 在列表上下文中计算,但在数组索引 ($foo[1]) 的情况下在标量上下文中计算。这没有任何功能影响。
      2. @foo[1] 发出警告。

      【讨论】:

        【解决方案5】:

        好问题 - 这里有一些区别:

        $a[0] = localtime; print @a;  # this prints: Tue Nov 1 18:51:13 2011  
        @a[0] = localtime; print @a;  # this prints the amount of seconds, e.g. 13
        
        $a[0] = grep{}, qw(6 2 8); print @a; # this prints: 3  
        @a[0] = grep{}, qw(6 2 8); print @a; # this prints: 6
        
        $a[0] = reverse ("a", "b"); print @a; # this prints: ba  
        @a[0] = reverse ("a", "b"); print @a; # this prints: b
        
        $a[0] = ("a", "b"); print @a;    # this prints: b  
        @a[0] = ("a", "b"); print @a;    # this prints: a
        

        切片是否为[1] 无关紧要。您可以通过查找在不同上下文中评估时给出不同结果的函数来创建更多示例。

        后一个(第4个)例子的解释:
        $a[0] 中的 $ 创建一个标量上下文。上下文会影响逗号运算符的工作方式,从而产生不同的结果:

        "二进制 "," 是逗号运算符。在标量上下文中,它计算左参数,丢弃该值,然后计算右参数并返回该值。"
        @987654321 @

        因此:b

        要理解以:@a[0] 开头的行,请考虑:

        ($a, $b, $c) = ("a", "b", "c", "d"); # here the "d" is discarded
        print $a, $b, $c; # this prints: abc
        
        ($a, $b)     = ("a", "b", "c");      # here the "c" is discarded  
        ($a)         = ("a", "b");           # here the "b" is discarded  
        ($a[0])      = ("a", "b");           # here the "b" is discarded  
        

        看起来,行首的括号创建了一个列表上下文。这几乎就是它所说的:http://docstore.mik.ua/orelly/perl4/prog/ch02_07.htm "分配给一个标量列表也会在右侧提供一个列表上下文,即使列表中只有一个元素"

        @ 在行首也会创建一个列表上下文:

        @a[0] = ("a", "b") 表示以与上述相同的方式评估 RHS,即丢弃“b”

        【讨论】:

        • 您应该使用backticks 格式化内联代码,并为代码块使用四个空格缩进。
        猜你喜欢
        • 2011-08-15
        • 1970-01-01
        • 2019-02-05
        • 1970-01-01
        • 2016-12-03
        • 1970-01-01
        • 1970-01-01
        • 2017-06-28
        • 2011-07-20
        相关资源
        最近更新 更多