如何在Perl中定义匿名标量引用?

时间:2015-08-07 13:43:54

标签: perl reference scalar

如何在Perl中正确定义匿名标量引用?

my $scalar_ref = ?;

my $array_ref = [];

my $hash_ref = {};

4 个答案:

答案 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也不是真的。制造穆斯的人决定顺其自然,但这无关紧要。

您可能想要的是没有默认值,只需将其设为ScalarRefrequired

请注意,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;