在 Perl 中传递标量引用

发布于 2024-11-04 23:55:39 字数 292 浏览 12 评论 0原文

我知道将标量传递给子实际上是传递引用,但由于我是 perl 新手,我仍然做了以下测试:

#!/usr/bin/perl
$i = 2;
subr(\$i);
sub subr{
    print $_[0]."\n";
    print $$_[0]."\n";
}

我认为第一行将打印一个地址,第二行将返回数字,但第二个是空行。有人指示我这样做:${$_[0]} 并打印出数字。但她不知道为什么没有 {} 它无法工作,以及为什么它与 {} 一起工作。那么到底发生了什么?

I know that passing a scalar to a sub is actually passing the reference, but since I am new to perl I still did the following test:

#!/usr/bin/perl
$i = 2;
subr(\$i);
sub subr{
    print $_[0]."\n";
    print $_[0]."\n";
}

I thought the first line is going to print an address and the second line is going to give be back the number, but the second one is a blank line. I was pointed by someone one else to do this: ${$_[0]} and it prints the number. But she didn't know the reason why without {} it is not working and why it is working with {}. So what has happened?

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

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

发布评论

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

评论(4

违心° 2024-11-11 23:55:39

这是因为你的第二个打印语句相当于这样做......

my $x = $_; print $x[0];

当你想要的是

my $x = $_[0]; print $x;

换句话说,取消引用发生在评估数组下标之前。

当你添加那些curl-wurlies时,它会告诉perl如何按照你的需要解释表达式;它将首先评估 $_[0],然后取消引用以获取值。

It's because your second print statement is equivalent to doing this...

my $x = $_; print $x[0];

When what you want is

my $x = $_[0]; print $x;

In other words, the de-referencing occurs before the array subscript is evaluated.

When you add those curl-wurlies, it tells perl how to interpret the expression as you want it; it will evaluate $_[0] first, and then de-reference to get the value.

狼性发作 2024-11-11 23:55:39

这是一个评估顺序。

  $_[0] is evaluated as {$_}[0]

这是标量变量 $_ 的引用的第 0 个元素。它首先获取引用,然后尝试找到它的第 0 个元素。

  ${$_[0]}

这是对数组@_ 的第 0 个元素的引用。它首先找到第 0 个元素,然后引用它。

如果您在代码顶部设置use strictuse warnings,您将在第一次尝试时看到大量有关未定义值的警告。

It's an order-of-evaluation thing.

  $_[0] is evaluated as {$_}[0]

This is the 0th element of the reference of the scalar variable $_. It's taking the reference first and then trying to find the 0th element of it.

  ${$_[0]}

This is a reference to the 0th element of the array @_. It's finding the 0th element first then taking a reference of that.

If you set use strict and use warnings at the top of your code you'll see plenty of warnings about undefined values from your first attempt.

旧竹 2024-11-11 23:55:39

$$_[0]$foo[0] 类似,只是用 $_ 代替数组名称。这意味着 $_ 被视为数组引用,并且表达式根本不涉及标量引用 $_[0]$_->[0] 是等效的,使用替代的 -> 语法。解除引用的语法可能看起来任意且难以记住,但有潜在的意义和顺序;一个很好的介绍位于 http://perlmonks.org/?node=References+quick +参考。

$$_[0] is like $foo[0], only with $_ in place of the array name. This means $_ is treated as an array reference, and the expression doesn't involve the scalar reference $_[0] at all. $_->[0] is equivalent, using the alternate -> syntax. Syntax for dereferencing may seem arbitrary and hard to remember, but there is underlying sense and order; a very good presentation of it is at http://perlmonks.org/?node=References+quick+reference.

删除会话 2024-11-11 23:55:39

您不必传递对 $i 的引用。当您将其作为 subr( $i )$_[0] 是 $i别名 >。

use strict;
use warnings;
use Test::More tests => 2;

sub subr{ $_[0]++ } # messing with exactly what was passed first
my $i=2;
is( $i, 2, q[$i == 2] );
subr($i);
is( $i, 3, q[$i == 3] );

另一个例子是这样的:

use strict;
use warnings;
use Test::More tests => 6;
use Test::Exception;

sub subr{ $_[0]++ }
my $i=2;
is( $i, 2, q[$i == 2] );
subr($i);
is( $i, 3, q[$i == 3] );

sub subr2 { $_[0] .= 'x'; }
dies_ok { subr2( 'lit' ); } 'subr2 *dies* trying to modify a literal';
lives_ok { 
    my $s = 'lit';
    subr2( $s );
    is( $s, 'litx', q[$s eq 'litx'] );
    subr2(( my $s2 = 'lit' ));
    is( $s2, 'litx', q[$s2 eq 'litx'] );
} 'subr2 lives with heap variables';

输出:

ok 1 - $i == 2
ok 2 - $i == 3
ok 3 - subr2 *dies* trying to modify a literal
ok 4 - $s eq 'litx'
ok 5 - $s2 eq 'litx'
ok 6 - subr2 lives with heap variables
1..6

You don't have to pass a reference to $i. The notation $_[0] is an alias for $i when you invoke it as subr( $i ).

use strict;
use warnings;
use Test::More tests => 2;

sub subr{ $_[0]++ } # messing with exactly what was passed first
my $i=2;
is( $i, 2, q[$i == 2] );
subr($i);
is( $i, 3, q[$i == 3] );

Another example is this:

use strict;
use warnings;
use Test::More tests => 6;
use Test::Exception;

sub subr{ $_[0]++ }
my $i=2;
is( $i, 2, q[$i == 2] );
subr($i);
is( $i, 3, q[$i == 3] );

sub subr2 { $_[0] .= 'x'; }
dies_ok { subr2( 'lit' ); } 'subr2 *dies* trying to modify a literal';
lives_ok { 
    my $s = 'lit';
    subr2( $s );
    is( $s, 'litx', q[$s eq 'litx'] );
    subr2(( my $s2 = 'lit' ));
    is( $s2, 'litx', q[$s2 eq 'litx'] );
} 'subr2 lives with heap variables';

Output:

ok 1 - $i == 2
ok 2 - $i == 3
ok 3 - subr2 *dies* trying to modify a literal
ok 4 - $s eq 'litx'
ok 5 - $s2 eq 'litx'
ok 6 - subr2 lives with heap variables
1..6
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文