Passing arrays to functions in Perl

不羁的心 提交于 2019-12-03 23:24:51
ysth

AFAIK, in both functions, arguments are passed by reference and in both functions we can change the elements of @array in the main program.

"change the elements of", yes. However, in the func(@array) case, the sub has no means to make other changes to the array (truncating it, pushing, popping, slicing, passing a reference to something else, even undef'ing it).

I would avoid using the term "passed by reference", since the mechanism is completely different than Perl's references. It is less overloaded :) to say that in the sub, @_'s elements start off aliased to the elements passed to the sub.

ikegami

It's impossible to pass arrays to subs. Subs take a list of scalars for argument. (And that's the only thing they can return too.)

You can pass a reference to an array:

func(\@array)

You can pass the elements of an array:

func(@array)

When should we use which?

If you want to pass more than just the elements of the array (e.g. pass $x, $y and @a), it can become tricky unless you pass a reference.

If you're going to process lists (e.g. sum mysub grep { ... } ...), you might not want to pass a reference.

If you want to modify the array (as opposed to just modifying the existing elements of the array), you need to pass a reference.

It can be more efficient to pass a reference for long arrays, since creating and putting one reference on the stack is faster than creating an alias for each element of a large array. This will rarely be an issue, though.

It's usually decided by one of the first two of the above. Beyond that, it's mostly a question of personal preference.


Also, how do I imitate pass-by-value in Perl?
sub foo {
   my ($x) = @_;   # Changing $x doesn't change the argument.
   ...
}

sub foo {
   my @a = @_;   # Changing @a or its contents
   ...           #    doesn't change the arguments.
}

func(\@array) passes a reference. func(@array) passes a list (of the elements in @array). As Keith pointed out, these elements are passed by reference. However, you can make a copy inside the sub in order to pass by value.

What you are after is this:

sub func {
    my @array = @_;
}

This will pass a copy of the arguments of func to @array, which is a local variable within the scope of the subroutine.

Documentation here

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!