2012-04-03 39 views
11

Tôi có một số mã không hoạt động theo cách tôi mong đợi và tôi đánh giá cao một số trợ giúp tìm hiểu cách làm cho nó hoạt động theo cách tôi mong đợi.Sửa đổi mảng trong chương trình con

Tôi muốn sử dụng chương trình con để sửa đổi mảng đầu vào. Tôi nghĩ rằng nếu tôi chuyển qua tham chiếu đến mảng, mọi thay đổi tôi đã thực hiện đối với mảng đó cũng sẽ được phản ánh trong phiên bản của người gọi. Nhưng nó dường như không hoạt động theo cách đó.


my @test_array = qw (zero one two three); 

shift_array(\@test_array); 
print "POST SUBROUTINE: $test_array[0]\n"; 

sub shift_array { 
    my @array = @{(shift)}; 
    shift @array; 
    print "AFTER SHIFT IN SUB: $array[0]\n"; 
} 

in này:

 
AFTER SHIFT IN SUB: one 
POST SUBROUTINE: zero 

tôi mong đợi nó để in one cả hai lần.

Vì vậy, câu hỏi của tôi là hai lần:

1) Tại sao nó không hoạt động theo cách tôi nghĩ? Không đi qua một tham chiếu đến một mảng tạo ra một bản sao của mảng?

2) Làm cách nào để nhận được hành vi mà tôi mong đợi? Làm thế nào để tôi có một chương trình con để trượt một hoặc nhiều phần tử ra khỏi mặt trước của bản sao của một mảng đầu vào của người gọi?

Cảm ơn trước vì bất kỳ thông tin chi tiết nào bạn có thể cung cấp.

Trả lời

9

Bởi vì my @array là một mảng mới mà bạn đã gán mảng ban đầu không tham chiếu đến. Đó là một bản sao.

Thay vì làm điều này:

sub shift_array { 
    my $array = shift; 
    shift(@$array); 
} 

Edit: tôi ban đầu cho biết dereferencing nó tạo ra vấn đề nhưng sử dụng @$array vẫn dereferencing nó. Như @mob đã chỉ ra, gán biến là những gì tạo mảng mới thay vì cập nhật tham chiếu hiện có.

+0

Wow. Đó là một sắc thái tôi không hiểu. Cảm ơn! – BlairHippo

+1

@mob bạn là chính xác. Chỉnh sửa câu trả lời của tôi để làm rõ – Cfreak

+2

lưu ý rằng với perl 5.14+ bạn có thể viết 'shift $ array' trong phần phụ và tham chiếu de xảy ra tự động. – mirod

0

Đây là một trong số (số ít) các trường hợp nguyên mẫu Perl hữu ích.

#!/usr/bin/perl 

use strict; 
use warnings; 

# Prototype forces the first argument to be a reference to an array  
sub shift_array (\@) { 
    my $array = shift; 
    shift(@$array); 
    print "AFTER SHIFT IN SUB: @$array[0]\n"; 
} 

my @test_array = qw (zero one two three); 

shift_array(@test_array); 
print "POST SUBROUTINE: $test_array[0]\n"; 
0

tôi thích để phù hợp hơn trong việc sử dụng tài liệu tham khảo mảng để giảm thiểu sự mơ hồ:

#!/usr/bin/perl 
use strict; 
use warnings; 

my @test_array = qw (zero one two three); 

shift_array(\@test_array); 
print "POST SUBROUTINE: $test_array[0]\n"; 

sub shift_array { 
    my $ref = shift; 
    shift @$ref; 
    print "AFTER SHIFT IN SUB: ${$ref}[0]\n"; 
} 
Các vấn đề liên quan