如果I',则[@{$myArray}]等同于Perl中的$myArray;我没有改变这些值?

如果I',则[@{$myArray}]等同于Perl中的$myArray;我没有改变这些值?,perl,Perl,我有一些Perl代码: { key => [@{$myArray}] } 我想将其重构为: { key => $myArray } 如果我不改变键所指向的值,那么这两个值在语义上是等价的吗?它将创建一个对具有相同内容的数组的不同引用。在数组从未更改的情况下,这在功能上是等效的,但如果有人稍后出现并执行类似操作: push @{ $p->{key} }, "foo"; 然后在前一种情况下,它将保持$myArray不变。在后者中,它将在使用$myArray的任何地方更

我有一些Perl代码:

{
  key => [@{$myArray}]
}
我想将其重构为:

{
  key => $myArray
}

如果我不改变
键所指向的值,那么这两个值在语义上是等价的吗?

它将创建一个对具有相同内容的数组的不同引用。在数组从未更改的情况下,这在功能上是等效的,但如果有人稍后出现并执行类似操作:

push @{ $p->{key} }, "foo";

然后在前一种情况下,它将保持
$myArray
不变。在后者中,它将在使用
$myArray
的任何地方更改值。如果您绝对不希望将来的任何更改改变原始版本,那么您提出的重构可能是有害的。

不,它们不是。即使
$data->{key}
引用的数组从未更改

$myArray
是对数组的引用
[@{$myArray}]
创建$myArray引用的数组的副本,然后引用该数组。复制数组有两种方式。它屏蔽了
$myArray
$data
所做的更改,但也屏蔽了
$data
$myArray
的更改。 即使你没有变异
$data->{key}
,它们仍然有语义上的差异。例如

my $myArray = ["a", "b", "c"];
$data->{key1} = $myArray;
$data->{key2} = [@{$myArray}];
$myArray->[1] = "q";

print $data->{key1}[1];  # q
print $data->{key2}[1];  # b

除非您完全控制
$myArray
$data
,否则重构是不安全的。

  • @{$h->{key}}
    已更改。(你提到的差异)

  • @$array
    已更改

  • $array
    不能作为数组取消引用(例如,
    $array
    是字符串)

  • $array
    是一个重载
    @{}
    的对象

  • @$array
    的元素很大或很神奇

    创建散列时,第一个代码段会复制元素,因此速度较慢,并且会占用更多内存。第二个代码段不会复制数组或元素的任何神奇方面(例如,如果数组是
    :共享的
    数组,或绑定到
    Tie::File
    )的数组)


  • 是的,这些数组将具有相同的内容,但它们的内存地址将是相同的different@HunterMcMillen听起来是一个很好的回答。他特别要求与你提到的不同。关于魔法的观点很好。这也会影响绑定和重载对象。@Schwern,只有少数重载对象会重载
    =
    。复制不会严格化。如果我没弄错的话,我想的是
    @{}
    。@Schwern,啊,是的,也是这样。我会添加它。如果我不控制
    $data
    ,这也是不安全的,对吗?@aaronstacy是的。你说你是这么做的,我没有涵盖它。我不清楚你所说的“即使<代码>键从未更改”是什么意思。哈希键不能更改。@Borodin我使用了OP的术语。只要
    $data->{key}
    引用的数组没有更改。