如何在Perl中正确定义匿名标量引用?
my $scalar_ref = ?;
my $array_ref = [];
my $hash_ref = {};
答案 0 :(得分:7)
如果你想要一些可变存储的引用,那么就没有特别简洁的直接语法。关于您可以管理的最好的是
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 = {};
答案 1 :(得分:4)
通常你只是声明并且不初始化它。
my $foo; # will be undef.
您必须考虑空哈希引用和空数组引用指向具有表示的数据结构。当取消引用它们时,它们都会给你一个空列表。
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
然而,as ikegami pointed out,它将是只读的,因为它不是变量。 LeoNerd provides a better approach for this in his answer
无论如何,我的观点是,当解除引用时,空哈希引用和空数组引用都包含空列表()
。这不是undef
而是没有。但是没有 nothing 作为标量值,因为并非一无所有的所有内容都是标量值。
my $a = [];
say ref $r; # ARRAY
say scalar @$r; # 0
say "'@$r'"; # ''
所以没有真正的方法来初始化 nothing 。您只能不初始化。但无论如何,穆斯将把它变成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
也不是真的。制造穆斯的人决定顺其自然,但这无关紧要。
您可能想要的是没有默认值,只需将其设为ScalarRef
和required
。
请注意,perlref没有说明初始化空标量引用。
答案 2 :(得分:2)
我不完全确定你为什么需要,但我建议:
my $ref = \undef;
print ref $ref;
或者也许:
my $ref = \0;
答案 3 :(得分:0)
@LeoNerd的答案是正确的。 另一种选择是使用临时的匿名哈希值:
my $scalar_ref = \{_=>undef}->{_};
$$scalar_ref = "Hello!\n";
print $$scalar_ref;