- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我认为我对 Perl 引用以及如何使用它们有所了解。我开始接触 Perl 5.005。现在我有一段用 Perl 5.32 新鲜编写的代码,其中一些数组引用操作的行为让我感到困惑。
这是我的最小示例:
#!/usr/bin/perl
my $array_ref = (); # create an anonymous array and keep a reference to it
my $another_ref = $array_ref; # assign the reference (not an array deep copy, or is it?)
print "Pushing foo and bar\n";
push @{ $array_ref }, "foo";
push @{ $array_ref }, "bar";
print "Array ref element count: " . $#{ $array_ref } . "\n";
print "Another ref element count: " . $#{ $another_ref } . "\n";
print "Pushing baz\n";
push @{ $array_ref }, "baz";
print "Array ref element count: " . $#{ $array_ref } . "\n";
print "Another ref element count: " . $#{ $another_ref } . "\n";
结果输出:
# ./test.pl
Pushing foo and bar
Array ref element count: 1
Another ref element count: -1
Pushing baz
Array ref element count: 2
Another ref element count: -1
我的生产代码创建一个空的匿名数组 = 获取对其的引用,然后将引用的副本存储在某些动态数据结构中,然后继续使用原始的“my”( local)引用,然后“我的”本地标签超出范围。对我来说奇怪的是,虽然元素确实被添加到最初获得的数组引用中,但它们不会通过“复制的引用”= 出现,就像行一样
my $another_ref = $array_ref;
行为更像是复制构造,我最终得到了一个新的独立数组。即,根据观察到的行为,它似乎执行了深度复制。Perl 没有报告任何语法错误。
然后我想到,在将一些元素推送到原始数组之后尝试 arrayref 赋值。源代码中移动了一行:
#!/usr/bin/perl
my $array_ref = (); # create an anonymous array and keep a reference to it
#my $another_ref = $array_ref; # moved below:
print "Pushing foo and bar\n";
push @{ $array_ref }, "foo";
push @{ $array_ref }, "bar";
my $another_ref = $array_ref; # moved here
print "Array ref element count: " . $#{ $array_ref } . "\n";
print "Another ref element count: " . $#{ $another_ref } . "\n";
print "Pushing baz\n";
push @{ $array_ref }, "baz";
print "Array ref element count: " . $#{ $array_ref } . "\n";
print "Another ref element count: " . $#{ $another_ref } . "\n";
结果输出:
# ./test.pl
Pushing foo and bar
Array ref element count: 1
Another ref element count: 1
Pushing baz
Array ref element count: 2
Another ref element count: 2
现在看起来确实像一个正确的“仅引用的副本”。
所以我得到了对空数组的引用的深拷贝,但得到了填充数组的浅拷贝?哎哟!这是一个功能吗?通过什么方式?
这让我想知道我是否介意。我确实可以选择在“初始”范围的末尾分配数组,其中匿名数组被实例化。如果到该范围结束时数组仍然为空,则稍后确实可以添加更多元素,但到那时原始引用将消失,并且无论如何我都只能通过“持久”引用访问数组=一致的结果 = 没有造成任何伤害,只是在我的特殊情况下需要注意一些事情。
最佳答案
声明 $array_ref
的第一行不会“创建匿名数组”
my $var = (); # just an uninitialized scalar
仅声明一个标量变量,并为其分配一个空列表,根本没有任何效果。† 该变量保持未初始化状态。人们可以通过打印它的 ref 来看到这一点。 ,它显示一个空字符串(不是 ARRAY
),或者尝试打印它,您会收到使用未初始化值的警告(不是 ARRAY(0x...)
),数组引用的字符串化)。或者使用Devel::Peek
。
因此,在再次声明该变量时将该变量分配给另一个变量没有任何效果,并且 $another_ref
只是另一个未初始化的、完全不相关的标量。
但是声明了一个标量,并且没有初始化它,仍然允许我们将其转换为引用。因此,当您取消引用它,将值插入其中时,确实会构造一个匿名数组(通过自动生存),然后
push @$var, 1; # now it "became" an array reference
$var
是一个数组引用。好吧,它是一个标量,其值是一个数组引用,所以没有什么非常奇怪的事情发生,‡这就是通常的做法:声明一个标量,然后为其分配/构造一个引用。然而,这可能会令人惊讶。
在第二次尝试中,$another_ref
确实被分配了一个数组引用,因为同时$array_ref
确实被“提升”为数组引用。 (但这不是“深层复制”,并且仅对于对没有元素引用的数组的引用有效。)
声明一个标量并将其放入数组引用中
my $array_ref = [];
这通常是不需要的,因为一旦以这种方式使用,用于数组引用的未初始化标量就会变成一个标量。
一个异常(exception)是,如果该标量需要传递到一个子例程中,该子例程需要能够判断它是否获得了引用;那么我们需要首先为其分配一个引用。
† 如果已定义变量,则会对其产生影响。对于数组,@ary = ();
清除所有值(但保留内存分配,与 undef @ary;
不同);对于标量,它分配一个 undef
。
‡ 不过,也许很奇怪的是,我们可能会将一个未定义的标量视为数组引用(通过取消引用它并将值推送到它上面),并且它确实变成了一个数组引用
关于Perl 5 : assignment of an anonymous arrayref, 数组仍然为空 = 复制构造?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73106099/
如果我的 Perl 程序使用 Perl 模块,它将如何确定在哪里可以找到包含模块代码的文件? 例如,如果程序包含: use MyModule1; # Example 1 us
我在一个文件中有一些不同格式的数字:8.3、0.001、9e-18。我正在寻找一种简单的方法来读取它们并存储它们而不会损失任何精度。这在 AWK 中很容易,但在 Perl 中是如何完成的呢?我只愿意使
我在一个文件中有一些不同格式的数字:8.3、0.001、9e-18。我正在寻找一种简单的方法来读取它们并存储它们而不会损失任何精度。这在 AWK 中很容易,但在 Perl 中是如何完成的呢?我只愿意使
我正在自学 Perl,并且在我的 Windows 8 64 位系统上安装了 Strawberry。 Strawberry 命令行似乎工作正常,我在 C 驱动器上的 Strawberry 文件夹中创建了
我在 Perl 模块 IO::Socket::SSL 中发现了一个错误,我可能会修复它,但是,我担心测试修复。我从 Debian 下载了源码包(因为我打算为它制作一个 Debian 包或补丁)并查看了
我有一个 perl 文件,它使用了两个 perl 模块 A.pm 和 B.pm。 但是在 B.pm 中我需要调用 A.pm 的子程序。即使我在 A.pm 中使用并尝试使用它,我仍然遇到未定义的错误。
有没有办法在 Perl 运行时加载整个模块?我原以为我用 autouse 找到了一个很好的解决方案,但以下代码无法编译: package tryAutouse2; use autouse 'tryAu
过去,我编写过许多 perl 模块,以及不止一些独立的 perl 程序,但我之前从未发布过多文件 perl 程序。 我有一个几乎处于 beta 阶段的 perl 程序,它将被开源发布。它需要一些数据文
我有 1 个 perl 脚本,我们在其中编写了几个子例程。例子: # Try_1.pl main(); sub main{ --- --- check(); } check { -- --} 现在,
似乎 CPAN 上的一些(很多?)模块部分是使用 XS 在 C 中实现的,如果需要,可以回退到纯 perl 实现。虽然这很聪明,但它显然会损害性能,我想知道它是否会发生,以便我可以解决问题。 有没有一
我对 perl 很陌生。我希望我可以从 perl 安装一些软件包,我这样做是这样的: perl -MCPAN -e 'install VM::EC2' 我猜它由于依赖而失败,它显示: Result:
给定一个 Perl 包 Foo.pm,例如 package Foo; use strict; sub bar { # some code here } sub baz { # more
我有一个用 Perl 编写的测试生成器。它生成连接到模拟器的测试。这些测试本身是用 Perl 编写的,并通过其 API 连接到模拟器。我希望生成的代码是人类可读的,这意味着我希望它能够正确缩进和格式化
我正在学习 Perl,非常新的用户。我可以知道这些 Perl 代码之间有什么区别吗? #!/usr/bin/perl & #!/usr/bin/perl -w 最佳答案 那不是 perl 代码,它是
我不认为这是一个重复的问题。这专门针对 Perl 模块附带的脚本。 通常,在安装多个 Perl 版本时,您可以将 perl 可执行文件标记为版本号 (perl5.32),这样它们就可以在 /whate
我有一个在文件中使用 Blowfish 加密的程序和第二个 perl 程序,它提示输入用于将其解密为字符串的密码,我希望不必将解密的源代码写入硬盘驱动器,尽管将它放在内存中并不是真正的问题,因为运行程
有没有人为 Perl 中的惰性求值列表找到了一个好的解决方案?我尝试了很多方法来改变类似的东西 for my $item ( map { ... } @list ) { } 进入懒惰的评估——例如,通
我安装了多个版本的 Perl。 我已经指定了要使用的版本。但是为了验证,我想从 .pl 脚本本身输出 Perl 的版本。 这可能吗? 在 Perl 脚本中解析“perl --version”的输出似乎
人们还经常问“我怎样才能编译 Perl?”而他们真正想要的是创建一个可以在机器上运行的可执行文件,即使他们没有安装 Perl。 我知道有几种解决方案: perl2exe靛蓝之星 它是商业的。我从未尝试
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它. 8年前关闭。 Improve this
我是一名优秀的程序员,十分优秀!