如何将变量传递给函数作为引用并在调用程序中更改它们而不返回 [英] How to pass variables to a function as reference and get them changed in caller without returning

查看:101
本文介绍了如何将变量传递给函数作为引用并在调用程序中更改它们而不返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将变量,列表和哈希传递给子例程,并从中获取更改而不返回.

I need to pass in a variable,list and a hash to a subroutine, and get back changes from it without returning.

此代码不起作用.

sub foo{
    my $one = {$_[0]};   
    my @list = @{$_[1]};
    my %hash = %{$_[2]};
    print("\n inside foo: ${one}\n");
    print("\n inside foo: $one @list $hash{'key'}\n");
    $one = 2;
    @list = (4,5,6);
    my %hash2;
    $hash2{'key'} = 'valueModified';    
    %hash = %hash2;
    print("\n inside foo after Mod: $one\n");
    print("\n inside foo after Mod: $one @list $hash{'key'}\n");
}

my $one = 1;
my @list = (1,2,3);
my %hash;
$hash{'key'} = 'value';
my @allLocalArgs = (\$one,\@list,\%hash);
foo(\@allLocalArgs);
print("\nafter foo modification: $one @list $hash{'key'}\n");

输出:

 inside foo: HASH(0x234a240)

 inside foo: HASH(0x234a240)  

 inside foo after Mod: 2

 inside foo after Mod: 2 4 5 6 valueModified

after foo modification: 1 1 2 3 value

谢谢.

推荐答案

原则上,实际上,在任何语言中,您都希望传递引用调用者,指针或引用中的数据结构的对象.在Perl中,这将作为参考-而您正在这样做.

In principle, and in practically any language, you'd want to pass objects that refer to data structures in the caller, pointers or references. In Perl, that would be a reference -- and you are doing that.

但是,然后在子目录中创建本地副本;子中的$one@list%hash sub的作用域本地化,掩盖/遮盖在调用范围内.对这些内容所做的更改不会超出sub的范围.

But then in the sub you create local copies; the $one, @list, and %hash in the sub are lexical variables local to sub's scope, masking/shadowing the ones in the calling scope. Changes to those don't do anything outside of sub's scope.

相反,直接使用您传递的引用来写入调用者的数据.

Instead, directly use the references that you passed in order to write to the caller's data.

sub foo { 

    my ($rscalar, $rary, $rhash) = @_;

    $$rscalar = 2;

    @$rary = (4,5,6);

    $rhash->{'key'} = 'valueModified'; 
}

foo(\$one, \@list, \%hash);

现在,调用代码中的

现在$one@list%hash已更改.有关使用参考的详细信息,请参见教程 perlreftut 和参考

Now $one, @list, and %hash in the calling code have been changed. For details of working with references please see tutorial perlreftut and reference perlref.

请注意,foo(\@allLocalArgs);使用参数传递数组的引用,因此子级接收一个元素-该数组的引用.您可以执行此操作,但是对于问题而言,它不是必需的,因此我将其删除并直接传递了参数列表.

Note that foo(\@allLocalArgs); passes the reference of the array with arguments, so the sub receives one element -- that array's reference. You can do that but for the point of the question it isn't needed so I removed it and passed the list of arguments directly.

要注意的另一件事是,参数在@_中是别名的-因此,如果在子级中直接使用@_,则可以在调用方中更改数据.因此,如果要将标量变量作为foo($one)传递,则子级中的$_[0] = 2会更改调用方中的$one.我认为,原则上最好避免这种情况;如果要更改呼叫者的数据,则应使其尽可能明确;通过参考.

Another thing to note is that arguments are aliased in @_ -- so if in the sub you work with @_ directly then you may change data in the caller. So if you were to pass a scalar variable as foo($one) then $_[0] = 2 in the sub changes $one in the caller. This is in principle best avoided in my opinion; if caller's data is to be changed that should be made as explicit as possible; pass the reference.

术语说明

A list 是一种难以捉摸的临时结构,用于在程序中四处移动数据.想一想堆栈中的一堆标量(值),这些标量(值)将被使用并消失.也许将参数传递给函数(foo($v1, $v2)),或形成字符串(join '', $v1, $v2),或创建匿名数组引用([$v1, $v2]),等等.

A list in Perl is an elusive, ephemeral structure used to move data around in a program; think of a bunch of scalars (values) on the stack somewhere, about to be used and disappear. Perhaps to pass arguments to a function (foo($v1, $v2)), or to form a string (join '', $v1, $v2), or to create an anonymous array reference ([$v1, $v2]), etc.

另一方面,数组是多值变量.就像哈希(关联数组)一样,它是一个多值变量,与标量相反,它是一个单值变量.

An array, on the other hand, is a multi-valued variable. Much like a hash (associative array) is a multi-valued variable, and as opposed to a scalar, being a single-valued variable.

对此已经写了很多;以下是一些容易出现的链接:有效的Perler文章(带有更多文章的链接),以及Stackoverflow页面 Perl数组与列表.

A lot has been written on this; here are a few links that came up readily: an Effective Perler article (with links to a few more articles), and a Stackoverflow page Perl array vs list.

简而言之,您正在询问标量,数组,哈希".

In short, you are asking about a "scalar, array, hash."

这篇关于如何将变量传递给函数作为引用并在调用程序中更改它们而不返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆