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

问题描述 投票:2回答:4

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

my $scalar_ref = ?;

my $array_ref = [];

my $hash_ref = {};

perl reference scalar
4个回答
4
投票

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

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 的事情。


9
投票

如果你想引用一些可变的存储,没有特别整洁的直接语法。你能做到的最好的是

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

2
投票

我不太清楚你为什么要这么做,但我建议:

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

或者..:

my $ref = \0; 

0
投票

@LeoNerd的答案是正确的. 另一个选择是使用一个临时的匿名哈希值:

my $scalar_ref = \{_=>undef}->{_};
$$scalar_ref = "Hello!\n";
print $$scalar_ref;
© www.soinside.com 2019 - 2024. All rights reserved.