2017-08-24 12 views
5

Có ai có thể giải thích câu lệnh push trong mã Perl sau đây cho tôi không? Tôi biết làm thế nào đẩy trong perl hoạt động nhưng tôi không thể hiểu những gì các đối số đầu tiên trong lệnh push sau đại diện. Tôi đang cố gắng diễn giải kịch bản của ai đó. Tôi đã cố gắng để print "@a\n"; nhưng nó chỉ in ARRAY(0x9aa370) mà làm cho tôi nghĩ rằng đẩy không làm bất cứ điều gì. Bất kỳ trợ giúp được đánh giá cao. Cảm ơn!Tài liệu tham khảo trong tác phẩm Perl như thế nào

my @a =(); 
my $b = 10; 
my $c = 'a'; 
push(@{$a[$b]}, $c); 
+2

https://metacpan.org/pod/perlreftut – melpomene

Trả lời

12

Hãy chia nhỏ nó.

Các @{...} được hiểu từ "Using References" in perlref

Anywhere bạn muốn đặt một định danh (hoặc chuỗi định danh) như một phần của một biến hoặc chương trình con tên, bạn có thể thay thế các định danh với một BLOCK trả về một tham chiếu đúng loại.

Vì vậy, những gì bên trong { ... } khối đã làm việc ra một tài liệu tham khảo mảng tốt hơn. Bạn có $a[$b] ở đó, một phần tử của @a tại chỉ mục $b, do đó phần tử đó phải là mảng arrayref.

Sau đó, @{...} bỏ qua nó và push es thành phần mới $c cho nó. Tổng cộng, $c được sao chép vào thành phần (duy nhất) của một mảng ẩn danh có tham chiếu tại chỉ số $b của mảng @a.

Và một phần quan trọng: vì trong thực tế không có mảng nào & dagger; ở đó, các cú đá autovivification và nó được tạo ra. Vì không có phần tử nào ở các chỉ mục trước $b chúng cũng được tạo, với giá trị undef.

Bây giờ xin làm việc thông qua

khi sử dụng perlref cho một tài liệu tham khảo đầy đủ.


Với cấu trúc dữ liệu phức tạp, rất hữu ích khi có thể nhìn thấy chúng và có các công cụ cho điều đó. Một người ta thường sử dụng nhiều nhất là cốt lõi Data::Dumper, và đây là một ví dụ với Data::Dump

perl -MData::Dump=dd -wE'@ary = (1); push @{$ary[3]}, "ah"; dd \@ary' 

với sản lượng

 
[1, undef, undef, ["ah"]] 

nơi [] bên chỉ ra một arrayref, với yếu tố duy nhất của nó là chuỗi ah.


& dagger; Chính xác hơn, một vô hướng undef vô hướng và do điều này xảy ra trong một bối cảnh lvalue tính năng tự động hóa được thực hiện. Cảm ơn ikegami để nhận xét. Xem ví dụ this post với các liên kết của nó.

+0

Re "* là có trong thực tế không có arrayref ở đó * ", Tốt hơn, bởi vì nó không xác định. Vì tự động hóa, 'push @ {$ ref}, LIST;' có hiệu quả ngắn đối với 'push @ {$ ref // = []}, LIST;' – ikegami

+0

@ikegami Cảm ơn bạn, đã thêm, dưới dạng chú thích cho bây giờ (có thể viết lại văn bản) – zdim

1

Tôi đã có một cuộc thảo luận trên này ngày hôm qua here

những gì nó có nghĩa là
@a là một mảng

$a[$b] 

được một ô trong mảng cú pháp @{} giúp perl hiểu rằng ô trong câu hỏi là một mảng để bạn có thể tạo sẵn các hoạt động push/pop trên đó.
nếu bạn làm

use Data::Dumper; 
print Dumper \@a; 

bạn sẽ thấy một cái gì đó như:

$VAR1 = [ 
      undef, 
      undef, 
      undef, 
      undef, 
      undef, 
      undef, 
      undef, 
      undef, 
      undef, 
      undef, 
      [ 
      'a' 
      ] 
     ]; 

như bạn có thể thấy, các tế bào thứ 11 là một mảng chứa các chữ 'a' là giá trị duy nhất của nó
đẩy hoạt động trên ô trống cũng có thể được viết là:

$a[$b] = [$c] 
+0

tôi sẽ đánh giá cao nếu xuống cử tri sẽ xác định tại sao họ xuống bình chọn, tôi muốn nâng cao chất lượng câu trả lời của tôi – Nullman

3

Hãy bắt đầu với hai khẳng định sau đây:

  • @a bắt đầu ra như là một mảng trống rỗng không có yếu tố này.
  • $b được gán giá trị của 10.

Bây giờ nhìn vào cấu trúc này:

@{$a[$b]}

Để hiểu chúng ta có thể bắt đầu ở giữa: $a[$b] chỉ số nguyên tố 10 của mảng @a.

Bây giờ chúng tôi có thể làm việc ra bên ngoài từ đó: @{...} coi nội dung của nó là tham chiếu đến một mảng. Vì vậy, @{$a[$b]} xử lý nội dung của phần tử 10 của mảng @a làm tham chiếu đến một mảng ẩn danh. Tức là, giá trị vô hướng chứa trong $a[10] là tham chiếu mảng.

Bây giờ lớp trong việc đẩy mạnh:

push @{$a[$b]}, $c;

Into the mảng vô danh tham chiếu trong phần 10 của @a bạn đang đẩy mạnh giá trị của $c, đó là nhân vật "a".Bạn có thể truy cập vào yếu tố đó như thế này:

my $value = $a[10]->[0]; # character 'a'

Hoặc viết tắt,

my $value = $a[10][0];

Nếu bạn đẩy giá trị khác vào @{$a[10]} sau đó bạn sẽ truy cập vào nó tại địa chỉ:

my $other_value = $a[10][1];

Nhưng còn khoảng $a[0] thông qua $a[9]? Bạn chỉ đang đẩy giá trị vào $a[$b], là $a[10]. Perl tự động mở rộng mảng để chứa phần tử thứ 11 đó ($a[10]), nhưng để lại giá trị trong $a[0] thông qua $a[9]undef. Bạn nói rằng bạn đã cố gắng này:

print "@a\n";

Interpolating một mảng thành một chuỗi gây ra yếu tố của nó được in với một khoảng trống giữa mỗi người. Vì vậy, bạn không thấy điều này:

ARRAY(0xa6f328)

Bạn thấy điều này:

ARRAY(0xa6f328)

... vì có mười chỗ trước phần tử thứ 11, trong đó có một tham chiếu mảng.

Nếu bạn đang chạy script của bạn với use warnings ở phía trên, bạn đã có thể thấy điều này thay vì:

Use of uninitialized value in join or string at scripts/mytest.pl line 12. 
Use of uninitialized value in join or string at scripts/mytest.pl line 12. 
Use of uninitialized value in join or string at scripts/mytest.pl line 12. 
Use of uninitialized value in join or string at scripts/mytest.pl line 12. 
Use of uninitialized value in join or string at scripts/mytest.pl line 12. 
Use of uninitialized value in join or string at scripts/mytest.pl line 12. 
Use of uninitialized value in join or string at scripts/mytest.pl line 12. 
Use of uninitialized value in join or string at scripts/mytest.pl line 12. 
Use of uninitialized value in join or string at scripts/mytest.pl line 12. 
Use of uninitialized value in join or string at scripts/mytest.pl line 12. 
      ARRAY(0xa6f328) 

... hoặc một cái gì đó khá giống nhau.

cấu trúc của bạn hiện trông như thế này:

@a = (undef,undef,undef,undef,undef,undef,undef,undef,undef,undef,['a'])

Nếu bạn muốn thực sự có được một cái nhìn vào những gì một cấu trúc dữ liệu có vẻ như, thay vì sử dụng một bản in đơn giản, làm một cái gì đó như thế này:

use Data::Dumper; 
print Dumper \@a; 
Các vấn đề liên quan