如何在Perl中正确定义一个匿名的标量引用?
my $scalar_ref = ?;
my $array_ref = [];
my $hash_ref = {};
通常你只需要声明而不初始化它。
my $foo; # will be undef.
你要考虑到,空的哈希 refs 和空的数组 refs 都指向一个有表示的数据结构。它们两个,当被dereferenced时,会给你一个空列表。
perldata 说(重点是我)。
实际上有两种空字符串(空字符串),一个定义的和一个 未定义者. 定义的版本只是一个长度为零的字符串,如""。未定义的版本是一个表示没有实际值的值,比如当出现错误时,或者在文件末尾,或者当你引用一个未初始化的变量或数组或哈希中的元素时。虽然在 Perl 的早期版本中,未定义的标量在第一次使用时可能会成为定义值,但除了 perlref 中解释的极少数自动生存的情况外,这种情况不再发生。您可以使用 defined() 操作符来确定一个标量值是否被定义 (这对数组或哈希没有意义),而使用 undef() 操作符来产生一个未定义的值。
所以一个 空标量 (实际上并没有说)将是 undef
. 如果你想让它成为一个参考,就把它变成一个参考。
use strict;
use warnings;
use Data::Printer;
my $scalar_ref = \undef;
my $scalar = $$scalar_ref;
p $scalar_ref;
p $scalar;
这样就会输出。
\ undef
undef
然而, 正如井上所言它将是只读的,因为它不是一个变量。LeoNerd在他的回答中提供了一个更好的方法。.
总之,我的观点是,一个空的hash ref和一个空的array ref在被派生时都包含一个空的列表。()
. 而这不是 undef
不过 毫无. 但没有 毫无 作为一个标量值,因为所有的东西都是以 不是没有 是一个标量值。
my $a = [];
say ref $r; # ARRAY
say scalar @$r; # 0
say "'@$r'"; # ''
所以没有真正的方法用 毫无. 你只能 不初始化. 但穆斯会把它变成 undef
无论如何,你可以做的是让它
你可以做的是让它 也许是标量参考.
use strict;
use warnings;
use Data::Printer;
{
package Foo;
use Moose;
has bar => (
is => 'rw',
isa => 'Maybe[ScalarRef]',
predicate => 'has_bar'
);
}
my $foo = Foo->new;
p $foo->has_bar;
p $foo;
say $foo->bar;
输出。
""
Foo {
Parents Moose::Object
public methods (3) : bar, has_bar, meta
private methods (0)
internals: {}
}
Use of uninitialized value in say at scratch.pl line 268.
产量: predicate
给出的数值是 不对 (空字符串 ""
). undef
也是不对的。做Moose的人决定用这个,但这真的不重要。
也许你想要的是不要有一个默认值,而只是把它变成一个 ScalarRef
一个 required
.
注意到 perlref 也没有说任何关于初始化一个空标量 ref 的事情。
如果你想引用一些可变的存储,没有特别整洁的直接语法。你能做到的最好的是
my $var;
my $sref = \$var;
或者更整洁
my $sref = \my $var;
或者如果你不想让变量本身再进入范围,你可以使用do块。
my $sref = do { \my $tmp };
这时你可以通过 $sref
的值,它所引用的标量的任何变化都会被其他人看到。
当然,这种技术对于数组或哈希引用也同样有效,只是有更整洁的语法,可以用 []
和 {}
:
my $aref = do { \my @tmp }; ## same as my $aref = [];
my $href = do { \my %tmp }; ## same as my $href = {};
我不太清楚你为什么要这么做,但我建议:
my $ref = \undef;
print ref $ref;
或者..:
my $ref = \0;
@LeoNerd的答案是正确的. 另一个选择是使用一个临时的匿名哈希值:
my $scalar_ref = \{_=>undef}->{_};
$$scalar_ref = "Hello!\n";
print $$scalar_ref;