Ý nghĩa của @_ trong Perl là gì?


Câu trả lời:


118

perldoc perlvar là nơi đầu tiên để kiểm tra bất kỳ thông tin biến Perl có tên đặc biệt nào.

Trích dẫn:

@_: Trong một chương trình con, mảng @_chứa các tham số được truyền cho chương trình con đó.

Bạn có thể tìm thêm chi tiết trong perldoc perlsub (chương trình con Perl) được liên kết từ perlvar:

Bất kỳ đối số nào được truyền vào sẽ hiển thị trong mảng @_.

Do đó, nếu bạn gọi một hàm có hai đối số, chúng sẽ được lưu trữ trong $_[0]$_[1].

Mảng @_là một mảng cục bộ , nhưng các phần tử của nó là bí danh cho các tham số vô hướng thực tế . Đặc biệt, nếu một phần tử $ _ [0] được cập nhật, thì đối số tương ứng sẽ được cập nhật (hoặc lỗi xảy ra nếu nó không thể cập nhật).

Nếu một đối số là mảng hoặc phần tử băm không tồn tại khi hàm được gọi, thì phần tử đó chỉ được tạo khi (và nếu) nó được sửa đổi hoặc tham chiếu đến nó được lấy. (Một số phiên bản Perl trước đó đã tạo phần tử cho dù phần tử đó có được gán cho hay không.) Việc gán cho toàn bộ mảng @_ sẽ loại bỏ răng cưa đó và không cập nhật bất kỳ đối số nào.


Cảm ơn, gần đây tôi chỉ quen với việc kiểm tra perldoc và tôi thấy các trang web hữu ích: perldoc.perl.org/perlvar.html Thật không tồi khi tạo một sơ khai perl để khởi chạy cái này trên web ... định dạng của một trang web giúp ích cho tôi rất nhiều.
aschultz

27

Thông thường, bạn mở rộng các tham số được truyền cho một phụ bằng cách sử dụng @_biến:

sub test{
  my ($a, $b, $c) = @_;
  ...
}

# call the test sub with the parameters
test('alice', 'bob', 'charlie');

Đó là cách được tuyên bố là đúng bởi tội phạm tội ác .


2
đây là một lần tôi không đồng ý perlcritic, cá nhân tôi nghĩ rằng điều này là tốt nhất cho một hàm, nhưng đối với một phương thức, nó hữu ích cho shiftbản thân tham chiếu, sau đó giải nén @_mảng. Điều này làm rõ rằng đây là một phương thức VÀ phương thức này nhận một số tham số nhất định
Joel Berger

Tôi có lẽ nên sử dụng / biết về PERLCritic trước đây, nhưng tôi đã không. Cảm ơn vì đã sử dụng nó trong ví dụ này. Đôi khi những thứ bạn tham khảo có thể giúp ai đó học được điều gì đó hoàn toàn mới đối với họ.
aschultz

10

Lần truy cập đầu tiên của một tìm kiếm choperl @_ biết điều này :

@_ là danh sách các tham số đến một phụ.

Nó cũng có một lời giải thích dài hơn và chi tiết hơn tương tự.


3
Trên thực tế, lần truy cập đầu tiên của tìm kiếm Google của bạn bây giờ liên kết đến chính trang này.
Gabriel Southern

... bảy năm sau, thời đại internet vĩnh cửu. Đó là lý do tại sao tôi vừa liên kết đến kết quả đầu tiên vừa đưa ra phần liên quan: chỉ phụ thuộc vào Google sẽ rất ngây thơ.
Piskvor rời tòa nhà vào

1
Đúng là nhiều năm sau, nhưng vẫn khó chịu khi đọc câu trả lời ngụ ý rằng bạn nên Google để có câu trả lời cho câu hỏi. Đó là thông tin vô nghĩa đối với ai đó đọc câu trả lời do kết quả của Google.
Gabriel Nam

Tôi không đồng ý. "Tìm kiếm vấn đề của bạn trước khi đặt câu hỏi" vẫn là bước 0. stackoverflow.com/help/how-to-ask Có lẽ làm phiền bạn - nhưng đó là một loạt các câu hỏi lặp đi lặp lại có thể được trả lời bằng cách truy vấn máy trước .
Piskvor rời tòa nhà vào

1
Có, tìm kiếm là bước đầu tiên chính xác, nhưng không cần thiết phải bao gồm hướng dẫn để tìm kiếm trong câu trả lời của bạn. Đó là thông tin thừa không mang lại giá trị gì, và thật trớ trêu vì nếu ai đó theo liên kết tìm kiếm trong câu trả lời của bạn, nó sẽ đưa họ trở lại nơi họ bắt đầu.
Gabriel Southern

10

Câu hỏi đặt ra là @_ phương tiện gì ở Perl. Câu trả lời cho câu hỏi đó là, trong chừng mực $_có nghĩa là ở Perl, @_cũng có nghĩa là chúng .

Dường như không ai đề cập đến khía cạnh quan trọng này về ý nghĩa của nó - cũng như của chúng .

Do đó, cả hai đều được sử dụng như đại từ hoặc đôi khi là chất bôi ngoài da.

Chúng thường có tiền thân danh nghĩa, mặc dù không phải lúc nào cũng vậy.


7

Bạn cũng có thể sử dụng shift cho các biến riêng lẻ trong hầu hết các trường hợp:

$var1 = shift;

Đây là một chủ đề mà bạn nên nghiên cứu thêm vì Perl có một số cách thú vị để truy cập thông tin bên ngoài bên trong quy trình phụ của bạn.


3
Tuyệt vời, bất cứ ai đã bỏ phiếu cho tôi chỉ đơn giản là đăng một cách khác để làm điều tương tự. Tôi nhận ra rằng tôi đã không trả lời câu hỏi trực tiếp bởi vì ai đó đã trả lời, nhưng tôi đã đưa ra một hình thức thay thế mà các lập trình viên perl mới thường bối rối.
hockfan86

5

Tất cả các "biến đặc biệt" của Perl được liệt kê trong trang tài liệu perlvar .


2

Ngoài ra, nếu một hàm trả về một mảng, nhưng hàm được gọi mà không gán dữ liệu trả về của nó cho bất kỳ biến nào như bên dưới. Ở đây split () được gọi, nhưng nó không được gán cho bất kỳ biến nào. Chúng tôi có thể truy cập dữ liệu trả về của nó sau này thông qua @_:

$str = "Mr.Bond|Chewbaaka|Spider-Man";
split(/\|/, $str);

print @_[0]; # 'Mr.Bond'

Thao tác này sẽ tách chuỗi $strvà thiết lập mảng @_.


1

@ được sử dụng cho một mảng.

Trong một chương trình con hoặc khi bạn gọi một hàm trong Perl, bạn có thể chuyển danh sách tham số. Trong trường hợp đó, @_có thể được sử dụng để chuyển danh sách tham số cho hàm:

sub Average{

    # Get total number of arguments passed.
    $n = scalar(@_);
    $sum = 0;

    foreach $item (@_){

        # foreach is like for loop... It will access every
        # array element by an iterator
        $sum += $item;
    }

    $average = $sum / $n;

    print "Average for the given numbers: $average\n";
}

Gọi hàm

Average(10, 20, 30);

Nếu bạn quan sát đoạn mã trên, hãy thấy foreach $item(@_)dòng ... Ở đây nó truyền tham số đầu vào.


Bạn nên luôn luôn use strict. Do đó, tôi đã chỉnh sửa chức năng phụ của bạn.
EverythingRightPlace

0

Đừng bao giờ cố gắng sửa thành biến @_ !!!! Họ không được chạm vào .. Hoặc bạn sẽ nhận được một số hiệu ứng không ngờ. Ví dụ...

my $size=1234;
sub sub1{
  $_[0]=500;
}
sub1 $size;

Trước khi gọi sub1 $ size chứa 1234. Nhưng sau 500 (!!) nên bạn Không sửa giá trị này !!! Bạn có thể chuyển hai hoặc nhiều giá trị và thay đổi chúng trong chương trình con và tất cả chúng sẽ được thay đổi! Tôi chưa bao giờ thấy hiệu ứng này được mô tả. Các chương trình tôi đã xem cũng để lại mảng @_ chỉ đọc. Và chỉ có vậy bạn mới có thể chuyển chương trình con nội bộ biến không thay đổi một cách an toàn Bạn phải luôn làm điều đó:

sub sub2{
  my @m=@_;
  ....
}

gán @_ cho các biến thủ tục chương trình con cục bộ và làm việc với chúng tiếp theo. Ngoài ra trong một số thuật toán đệ quy sâu trả về mảng, bạn có thể sử dụng cách tiếp cận này để giảm bộ nhớ được sử dụng cho các vars cục bộ. Chỉ khi trả về mảng @_ giống nhau.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.