Như những người khác đã lưu ý, các thuật ngữ "gõ mạnh" và "gõ yếu" có rất nhiều ý nghĩa khác nhau mà không có câu trả lời duy nhất cho câu hỏi của bạn. Tuy nhiên, vì bạn đặc biệt đề cập đến Perl trong câu hỏi của bạn, hãy để tôi cố gắng giải thích theo nghĩa nào Perl được gõ yếu.
Vấn đề là, trong Perl, không có thứ gọi là "biến số nguyên", "biến float", "biến chuỗi" hay "biến boolean". Trong thực tế, theo như người dùng có thể (thường) nói, thậm chí không có các giá trị nguyên, float, chuỗi hoặc boolean : tất cả những gì bạn có là "vô hướng", đó là tất cả những điều này cùng một lúc. Vì vậy, bạn có thể, ví dụ, viết:
$foo = "123" + "456"; # $foo = 579
$bar = substr($foo, 2, 1); # $bar = 9
$bar .= " lives"; # $bar = "9 lives"
$foo -= $bar; # $foo = 579 - 9 = 570
Tất nhiên, như bạn lưu ý chính xác, tất cả những điều này có thể được xem như là kiểu ép buộc. Nhưng vấn đề là, trong Perl, các loại luôn bị ép buộc. Trên thực tế, người dùng khá khó để biết "loại" bên trong của biến có thể là gì: tại dòng 2 trong ví dụ của tôi ở trên, hỏi xem giá trị của $bar
chuỗi "9"
là số hay số 9
là vô nghĩa, vì, như, như Perl có liên quan, đó là những điều tương tự . Thật vậy, thậm chí có thể một vô hướng Perl có thể có cả chuỗi và giá trị số cùng một lúc, ví dụ như trường hợp $foo
sau dòng 2 ở trên.
Mặt trái của tất cả những điều này là, vì các biến Perl được tháo gỡ (hoặc, đúng hơn, không để lộ kiểu bên trong của chúng cho người dùng), các toán tử không thể bị quá tải để làm những việc khác nhau cho các loại đối số khác nhau; bạn không thể chỉ nói "toán tử này sẽ thực hiện X cho các số và Y cho các chuỗi", bởi vì toán tử không thể (không) cho biết loại đối số của nó là giá trị nào.
Do đó, ví dụ, Perl có và cần cả toán tử cộng số ( +
) và toán tử nối chuỗi ( .
): như bạn đã thấy ở trên, việc thêm chuỗi ( "1" + "2" == "3"
) hoặc nối các số ( 1 . 2 == 12
) là hoàn toàn tốt . Tương tự như vậy, các nhà khai thác so sánh số ==
, !=
, <
, >
, <=
, >=
và <=>
so sánh các giá trị số của các đối số của họ, trong khi các nhà khai thác chuỗi so sánh eq
, ne
, lt
, gt
, le
, ge
và cmp
so sánh chúng tự từ điển như dây đàn. Vì vậy 2 < 10
, nhưng 2 gt 10
(nhưng "02" lt 10
, trong khi "02" == 2
). (Nhắc bạn, một số ngôn ngữ khác , như JavaScript, cố gắng điều chỉnh kiểu gõ yếu như Perl trong khicũng làm quá tải toán tử. Điều này thường dẫn đến sự xấu xí, như mất tính kết hợp cho +
.)
(Điểm nổi bật của thuốc mỡ ở đây là, vì lý do lịch sử, Perl 5 có một vài trường hợp góc, giống như các toán tử logic bitwise, hành vi của chúng phụ thuộc vào biểu diễn bên trong của các đối số của chúng. đại diện nội bộ có thể thay đổi vì những lý do đáng ngạc nhiên, và do đó, việc dự đoán những gì các nhà khai thác đó làm trong một tình huống nhất định có thể khó khăn.)
Tất cả những gì đã nói, người ta có thể lập luận rằng Perl không có loại mạnh; chúng không phải là loại bạn có thể mong đợi. Cụ thể, ngoài loại "vô hướng" đã thảo luận ở trên, Perl còn có hai loại có cấu trúc: "mảng" và "hàm băm". Chúng rất khác biệt so với vô hướng, đến điểm mà các biến Perl có các sigils khác nhau biểu thị loại của chúng ( $
đối với vô hướng, @
đối với mảng, %
đối với hàm băm) 1 . Có những quy tắc ép buộc giữa các loại, vì vậy bạn có thể viết ví dụ %foo = @bar
, nhưng nhiều người trong số họ là khá lossy: ví dụ, $foo = @bar
giao cho chiều dài của mảng @bar
đến$foo
, không phải nội dung của nó. (Ngoài ra, có một vài loại lạ khác, như kiểu chữ và tay cầm I / O, mà bạn không thường thấy bị lộ.)
Ngoài ra, một nhược điểm nhỏ trong thiết kế đẹp này là sự tồn tại của các loại tham chiếu, là một loại vô hướng đặc biệt (và có thể được phân biệt với các vô hướng thông thường, sử dụng ref
toán tử). Có thể sử dụng các tham chiếu như các vô hướng bình thường, nhưng các giá trị chuỗi / số của chúng không đặc biệt hữu ích và chúng có xu hướng mất tính tham chiếu đặc biệt nếu bạn sửa đổi chúng bằng các phép toán vô hướng bình thường. Ngoài ra, bất kỳ biến Perl 2 nào cũng có thể được chỉnh bless
sửa thành một lớp, biến nó thành một đối tượng của lớp đó; hệ thống lớp OO trong Perl có phần trực giao với hệ thống kiểu nguyên thủy (hay không chữ) được mô tả ở trên, mặc dù nó cũng "yếu" theo nghĩa là gõ vịtmô hình. Ý kiến chung là, nếu bạn thấy mình đang kiểm tra lớp của một đối tượng trong Perl, bạn đang làm gì đó sai.
1 Trên thực tế, sigil biểu thị loại giá trị được truy cập, do đó, ví dụ vô hướng đầu tiên trong mảng @foo
được ký hiệu $foo[0]
. Xem perlfaq4 để biết thêm chi tiết.
2 Đối tượng trong Perl (thường) được truy cập thông qua các tham chiếu đến chúng, nhưng cái thực sự có bless
ed là biến (có thể ẩn danh) mà các điểm tham chiếu đến. Tuy nhiên, phước lành thực sự là một thuộc tính của biến, không phải là giá trị của nó, vì vậy, việc gán biến may mắn thực sự cho một biến khác chỉ mang lại cho bạn một bản sao nông cạn, không được ban phước của nó. Xem perlobj để biết thêm chi tiết.