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

How do I define an anonymous scalar ref in Perl?

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

my $scalar_ref = ?;

my $array_ref = [];

my $hash_ref = {};

通常你只是声明而不是初始化它。

my $foo; # will be undef.

您必须考虑空哈希引用和空数组引用指向具有表示的数据结构。当取消引用时,它们都会给你一个空列表。

perldata 说(强调我的):

There are actually two varieties of null strings (sometimes referred to as "empty" strings), a defined one and an undefined one. The defined version is just a string of length zero, such as "" . The undefined version is the value that indicates that there is no real value for something, such as when there was an error, or at end of file, or when you refer to an uninitialized variable or element of an array or hash. Although in early versions of Perl, an undefined scalar could become defined when first used in a place expecting a defined value, this no longer happens except for rare cases of autovivification as explained in perlref. You can use the defined() operator to determine whether a scalar value is defined (this has no meaning on arrays or hashes), and the undef() operator to produce an undefined value.

所以 空标量 (实际上并没有说)将是 undef。如果你想让它成为一个参考,就把它做成一个。

use strict;
use warnings;
use Data::Printer;

my $scalar_ref = \undef;
my $scalar = $$scalar_ref;

p $scalar_ref;
p $scalar;

这将输出:

\ undef
undef

然而,, it will be read-only because it's not a variable. .


无论如何,我的观点是,一个空的散列引用和一个空的数组引用在取消引用时都包含一个空列表 ()。那不是 undef,而是 nothing。但是没有 nothing 作为标量值,因为所有 not nothing 都是标量值。

my $a = [];

say ref $r;     # ARRAY
say scalar @$r; # 0
say "'@$r'";    # ''

所以没有真正的方法可以用 nothing 初始化。只能不能初始化。但是 Moose 无论如何都会把它变成 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 的人决定接受它,但这并不重要。

可能您想要的不是默认值,而是将其设置为 ScalarRefrequired


请注意 perlref 也没有说明有关初始化空标量引用的任何内容。

我不完全确定你为什么需要这样做,但我建议:

my $ref = \undef;
print ref $ref;

或者也许:

my $ref = [=11=]; 

如果你想引用一些可变存储,没有特别简洁的直接语法。您可以管理的最好的是

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 = {};

@LeoNerd 的回答很准确。 另一种选择是使用临时匿名哈希值:

my $scalar_ref = \{_=>undef}->{_};
$$scalar_ref = "Hello!\n";
print $$scalar_ref;