Passing arrays to functions in Perl

前端 未结 3 1244
北荒
北荒 2021-02-19 04:03

I think I have misunderstood some aspects of argument passing to functions in Perl. What\'s the difference between func(\\@array) and func(@array)?

相关标签:
3条回答
  • 2021-02-19 04:30

    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.

    0 讨论(0)
  • 2021-02-19 04:35

    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

    0 讨论(0)
  • 2021-02-19 04:46

    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.
    }
    
    0 讨论(0)
提交回复
热议问题