此示例代码中数组引用的范围重要吗

发布于 2025-01-07 19:41:55 字数 316 浏览 0 评论 0原文

#!/usr/bin/perl

    A();
    B();

    sub A {
        my @array = qw(value_1 value_2);
        $array_ref = \@array;
    }

    sub B {
        foreach my $i ( @{$array_ref} ) {
            print "Array Value: $i \n";
        }
    }

由于数组是使用“my”关键字声明的,数组引用是否会丢失? 任何人都可以向我介绍一下这一点吗?

#!/usr/bin/perl

    A();
    B();

    sub A {
        my @array = qw(value_1 value_2);
        $array_ref = \@array;
    }

    sub B {
        foreach my $i ( @{$array_ref} ) {
            print "Array Value: $i \n";
        }
    }

Since the array is declared using the 'my' keyword, could the array reference be lost ?
Can any one brief me over this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

断肠人 2025-01-14 19:41:55

不,变量的作用域会过期,但内存地址不会过期。数据将保留。

这不是你可以简单尝试一下的吗? =)我只是复制/粘贴你的代码并尝试了一下,效果很好。

不过,为了正确封装,您实际上应该返回数组引用:

B(A());
# Or
my $aref = A();
B($aref);

sub A {
        my @array = qw(value_1 value_2);
        return \@array;
}

sub B {
    my $array_ref = shift;
    foreach my $i ( @$array_ref ) {
        print "Array Value: $i \n";
    }
}

No, the scope of the variable expires, but not the memory address. The data will remain.

Isn't this something you could have simply tried? =) I just copy/pasted your code and tried it, and it worked fine.

For proper encapsulation, though, you really should return the array ref instead:

B(A());
# Or
my $aref = A();
B($aref);

sub A {
        my @array = qw(value_1 value_2);
        return \@array;
}

sub B {
    my $array_ref = shift;
    foreach my $i ( @$array_ref ) {
        print "Array Value: $i \n";
    }
}
羁〃客ぐ 2025-01-14 19:41:55

我绝对推荐

use strict;

在 Perl 脚本中使用(把它放在最开始)。在这种情况下,它会抱怨 $array_ref 未声明为全局的。这可能是造成混乱的主要根源:您使用 $array_ref 而不以任何方式声明它,因此它被视为全局变量。

数组内容本身被保留,因为它被这个变量引用,所以引用计数保持大于 0(perl 在内部使用引用计数来跟踪何时删除变量)。

当然,建议使用 TLP 帖子(没有全局变量)中所示的方法。

I definitely recommend using

use strict;

in Perl scripts (put it on the very beginning). In this very case it will complain about $array_ref being undeclared global. And it is likely the main source of the confusion: you use $array_ref without declaring it in any way, so it is treated as a global variable.

The array content itself is kept because it is referenced by this very variable so reference count remains greater than 0 (perl uses reference counting internally to keep track of when to remove variables).

Of course approach like shown in TLP posts (without globals) is to be recommended.

烟织青萝梦 2025-01-14 19:41:55

实际上,有一个很好的理由在此使用 my示例。
实际上,您希望每次通过子例程都重新创建变量,否则您将更改之前获得的值。

use strict;
use warnings;
use 5.10.1;

my @array;
sub A{
  push @array, scalar @array; # add the length of @array to the end
  return \@array;
}

my @list;

for( 'A'..'D' ){
  my $current = A();
  push @list, $current;
  say join ' ', @$current;
}

say '';

say join ' ', @$_ for @list;
0
0 1
0 1 2
0 1 2 3

0 1 2 3
0 1 2 3
0 1 2 3
0 1 2 3

请注意 @array 的每个副本都是相同的。


这就是为什么每次调用子例程时都需要一个新副本的原因。

use strict;
use warnings;
use 5.10.1;

sub A{
  state $iter = 0;
  my @array;
  push @array, 0..$iter++;
  return \@array;
}

my @list;

for( 'A'..'D' ){
  my $current = A();
  push @list, $current;
  say join ' ', @$current;
}

say '';

say join ' ', @$_ for @list;
0
0 1
0 1 2
0 1 2 3

0
0 1
0 1 2
0 1 2 3

Actually there is a very good reason to use my in this example.
You actually want the variable to be re-created every time through the subroutine, otherwise you would change the values that you got earlier.

use strict;
use warnings;
use 5.10.1;

my @array;
sub A{
  push @array, scalar @array; # add the length of @array to the end
  return \@array;
}

my @list;

for( 'A'..'D' ){
  my $current = A();
  push @list, $current;
  say join ' ', @$current;
}

say '';

say join ' ', @$_ for @list;
0
0 1
0 1 2
0 1 2 3

0 1 2 3
0 1 2 3
0 1 2 3
0 1 2 3

Notice how every copy of @array is identical.


This is why you need a new copy for every time the subroutine is called.

use strict;
use warnings;
use 5.10.1;

sub A{
  state $iter = 0;
  my @array;
  push @array, 0..$iter++;
  return \@array;
}

my @list;

for( 'A'..'D' ){
  my $current = A();
  push @list, $current;
  say join ' ', @$current;
}

say '';

say join ' ', @$_ for @list;
0
0 1
0 1 2
0 1 2 3

0
0 1
0 1 2
0 1 2 3
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文