2010-05-22 21 views
7

Trong perl, dấu ngoặc đơn được sử dụng để ghi đè quyền ưu tiên (như trong hầu hết các ngôn ngữ lập trình) cũng như để tạo danh sách. Làm cách nào tôi có thể biết liệu một cặp parens cụ thể có được coi là cấu trúc nhóm hay danh sách một phần tử không?Làm cách nào để biết một tập hợp các mã parens trong mã Perl có hoạt động như nhóm các nhóm hoặc tạo thành một danh sách không?

Ví dụ: tôi chắc chắn đây là một vô hướng và không phải là danh sách một phần tử: (1 + 1)
Nhưng còn những biểu thức phức tạp hơn thì sao? Có cách nào dễ dàng để nói không?

+0

Tôi cho rằng tôi gần như lo lắng về việc vô tình gán danh sách một phần tử có chứa kết quả thay vì kết quả cho chính nó thành vô hướng. Nhưng nếu tôi đọc các câu trả lời chính xác, điều này thực sự là không thể, trừ khi tôi làm một cái gì đó như '$ x = @ {[1 + 1]};'. Dường như việc gán một danh sách cho một vô hướng khác với việc gán một mảng cho một vô hướng. Điều gì sẽ xảy ra nếu bạn gán một danh sách có chứa một mảng vào một vô hướng? '$ x = (@list);' –

+0

Trong một nhiệm vụ, phía bên trái xác định bối cảnh trong đó phía bên phải sẽ được đánh giá. Vì vậy, khi bạn gán một mảng cho một biến vô hướng, mảng được đánh giá trong ngữ cảnh vô hướng. Một mảng được đánh giá trong ngữ cảnh vô hướng trả về số lượng các mục trong mảng. Cả hai ví dụ trong nhận xét của bạn đều thuộc danh mục đó. Cũng lưu ý rằng ở đây chúng ta đang nói về việc đánh giá một mảng trong ngữ cảnh vô hướng. Chúng ta không nói về một danh sách trong ngữ cảnh vô hướng, bởi vì không có danh sách trong ngữ cảnh vô hướng. – FMc

+0

Tôi đoán tôi đã luôn luôn nghĩ về danh sách và mảng về cơ bản là tương đương và có thể hoán đổi cho nhau, nhưng chúng không. –

Trả lời

16

Ba nguyên tắc chính là hữu ích ở đây:

Bối cảnh là vua. Việc đánh giá ví dụ của bạn (1 + 1) phụ thuộc vào ngữ cảnh.

$x = (1 + 1); # Scalar context. $x will equal 2. Parentheses do nothing here. 
@y = (1 + 1); # List context. @y will contain one element: (2). 
       # Parens do nothing (see below), aside from following 
       # syntax conventions. 

Trong một bối cảnh vô hướng, không có những điều như một danh sách. Để thấy điều này, hãy cố gắng chỉ định những gì xuất hiện làm danh sách cho biến vô hướng. Cách suy nghĩ về điều này là tập trung vào hành vi của toán tử dấu phẩy: trong ngữ cảnh vô hướng, nó đánh giá đối số bên trái của nó, ném giá trị đó đi, sau đó đánh giá đối số đúng của nó và trả về giá trị đó. Trong ngữ cảnh danh sách, toán tử dấu phẩy sẽ chèn cả hai đối số vào danh sách.

@arr = (12, 34, 56); # Right side returns a list. 

$x = (12, 34, 56); # Right side returns 56. Also, we get warnings 
         # about 12 and 34 being used in void context. 

$x = (@arr, 7);  # Right side returns 7. And we get a warning 
         # about using an array in a void context. 

Dấu ngoặc đơn không tạo danh sách. Toán tử dấu phẩy tạo danh sách (miễn là chúng ta đang ở trong ngữ cảnh danh sách). Khi nhập danh sách trong mã Perl, dấu ngoặc đơn là cần thiết vì lý do ưu tiên - không phải vì lý do tạo danh sách. Một vài ví dụ:

  • Các dấu ngoặc đơn không có hiệu lực: chúng ta đang đánh giá một mảng trong vô hướng bối cảnh, vì vậy phía bên phải trả về kích thước mảng.

    $x = (@arr); 
    
  • Không cần tạo dấu ngoặc đơn để tạo danh sách có một thành phần.

    @arr = 33;   # Works fine, with @arr equal to (33). 
    
  • Nhưng dấu ngoặc đơn là cần thiết với nhiều mục - vì lý do ưu tiên.

    @arr = 12, 34, 56; # @arr equals (12). And we get warnings about using 
            # 34 and 56 in void context. 
    
8
  1. Context.
  2. Dấu ngoặc đơn không có vai trò bạn nghĩ rằng họ có trong việc tạo danh sách.

Ví dụ:

$x = 1 + 1; # $x is 2. 
$x = (1 + 1); # $x is 2. 
@x = 1 + 1; # @x is (2). 
@x = (1 + 1); # @x is (2). 

$x = (1 + 1, 1 + 2); # $x is 3. 
@x = (1 + 1, 1 + 2); # @x is (2, 3). 

Nói đại khái, trong danh sách bối cảnh các nhà điều hành dấu phẩy tách hạng mục của một danh sách; trong ngữ cảnh vô hướng, toán tử dấu phẩy là dấu phẩy nối tiếp C, đánh giá các cạnh trái và phải của nó, và trả về giá trị của cạnh phải. Trong ngữ cảnh vô hướng, dấu ngoặc đơn biểu thức nhóm để ghi đè thứ tự các hoạt động, và trong ngữ cảnh danh sách, dấu ngoặc đơn làm ... chính xác điều tương tự, thực sự.Lý do chúng thích hợp trong giao để mảng là thế này:

# Comma has precedence below assignment. 
# @a is assigned (1), 2 and 3 are discarded. 
@a = 1, 2, 3; 

# @a is (1, 2, 3). 
@a = (1, 2, 3); 

Đối với câu hỏi của bạn "nó là một đại lượng vô hướng hoặc một danh sách một phần tử", nó chỉ là không phải là một câu hỏi có ý nghĩa để hỏi của một biểu thức trong sự cô lập , vì bối cảnh. Trong ngữ cảnh danh sách, mọi thứ đều là danh sách; trong ngữ cảnh vô hướng, không có gì.

Đề nghị đọc: perlop, perldata, Lập trình Perl.

+0

Tôi thích Deparse để hiển thị toán tử dấu phẩy: perl -MO = Deparse -le 'my @s = 1,3,4; in "@s" ' BEGIN {$/= "\ n"; $ \ = "\ n"; } my (@s) = 1, '???', '???'; in "@s"; -cú pháp OK –

Các vấn đề liên quan