0

我这样做:

my @items = [];

sub pushItem {
   my $itemId = "i" . sprintf("%d", $_[0]);
   push(@items, $itemId);
}

sub popItems {
   $itemsXml = "<key>items</key>\n<array>\n";

   foreach (@items) {
      $itemsXml .= "<string>$_</string>\n";
   }

   $itemsXml .= "</array>\n";

   return $itemsXml;
}

pushItem(0);
pushItem(1);
pushItem(2);
print popItems();

我明白了:

 <key>items</key>
 <array>
 <string>ARRAY(0x7fa1730070d0)</string>
 <string>i0</string>
 <string>i1</string>
 <string>i2</string>
 </array>

问题当然是:

<string>ARRAY(0x7fa1730070d0)</string>
4

3 回答 3

5
my @items = [];

应该

my @items = ();
于 2013-03-06T22:09:04.190 回答
3

[]创建一个数组和对该数组的引用,并返回后者。这意味着@items除了创建之外,以下内容还填充了对第二个数组的引用@items

 my @items = [];

你只是想要

 my @items;

如果你坚持给它分配一些东西,你会想给它分配一个零标量列表,你可以这样做:

 my @items = ();

但实际上,这只是一种浪费(因为您正在清除一个空数组)并且它增加了不必要的复杂性(什么都不做的代码)。


需要明确的是,@items = ();(相对于my @items = ();)仍然有用,尽管很少。我认为我唯一一次使用它是在以下形式的代码中:

my @buf;
while (my $item = get()) {
   if (check($item)) {
      something(@buf);
      @buf = ();
   }

   push @buf, $item;
}

something(@buf) if @buf;
于 2013-03-06T22:12:12.277 回答
2

你的问题是你的第一行:

my @items = [];

它应该是:

my @items = ();

问题是您已经为数组@items 的第一个元素分配了一个数组引用,然后您将一堆其他值推送到它上面。

如果您使用括号对其进行初始化,它会执行您想要的操作,即创建一个空数组。如果您注释掉对 pushItem 的调用并运行脚本,这会变得更加明显。

于 2013-03-06T22:15:28.417 回答