Chuyển đổi ngầm là hoàn toàn có thể làm. Tình huống mà bạn gặp rắc rối là khi bạn không biết cách nào đó nên hoạt động.
Một ví dụ về điều này có thể được nhìn thấy trong Javascript nơi người +
vận hành làm việc theo những cách khác nhau vào những thời điểm khác nhau.
>>> 4 + 3
7
>>> "4" + 3
43
>>> 4 + "3"
43
Nếu một trong các đối số là một chuỗi, thì +
toán tử là một chuỗi nối, nếu không nó là phép cộng.
Nếu bạn được cung cấp một đối số và không biết đó là một chuỗi hay một số nguyên và muốn thực hiện bổ sung với nó, nó có thể là một mớ hỗn độn.
Một cách khác để giải quyết vấn đề này là từ di sản Cơ bản (mà perl theo sau - xem Lập trình là Khó, Hãy viết kịch bản ... )
Trong Cơ bản, len
hàm chỉ có nghĩa là được gọi trên Chuỗi (tài liệu cho trực quan cơ bản : "Bất kỳ biểu thức hoặc tên biến hợp lệ nào. Nếu Biểu thức là loại Object, hàm Len sẽ trả về kích thước vì nó sẽ được ghi vào tệp bởi chức năng FilePut. ").
Perl theo khái niệm này của bối cảnh. Sự nhầm lẫn tồn tại trong JavaScript với các loại chuyển đổi ngầm định cho +
toán tử đôi khi là phép cộng và đôi khi phép nối không xảy ra trong perl vì luôn luôn+
là phép cộng và luôn luôn là phép nối..
Nếu một cái gì đó được sử dụng trong ngữ cảnh vô hướng, thì nó là vô hướng (ví dụ: sử dụng danh sách làm vô hướng, danh sách này hoạt động như thể nó là một số tương ứng với độ dài của nó). Nếu bạn sử dụng toán tử chuỗi ( eq
để kiểm tra đẳng thức, cmp
để so sánh chuỗi) thì vô hướng được sử dụng như thể đó là một chuỗi. Tương tự, nếu một cái gì đó được sử dụng trong ngữ cảnh toán học ( ==
để kiểm tra đẳng thức và <=>
so sánh số), thì vô hướng được sử dụng như thể nó là một số.
Nguyên tắc cơ bản cho tất cả các chương trình là "làm điều gây ngạc nhiên cho người đó ít nhất". Điều này không có nghĩa là không có bất ngờ trong đó, nhưng nỗ lực là làm cho người đó ngạc nhiên ít nhất.
Đi đến một người anh em họ thân thiết của perl - php, có những tình huống mà một nhà điều hành có thể hành động trên một cái gì đó trong bối cảnh chuỗi hoặc số và hành vi có thể gây ngạc nhiên cho mọi người. Các ++
nhà điều hành là một ví dụ như vậy. Về số lượng, nó hoạt động chính xác như mong đợi. Khi hành động trên một chuỗi, chẳng hạn như "aa"
, nó sẽ tăng chuỗi ( $foo = "aa"; $foo++; echo $foo;
in ab
). Nó cũng sẽ cuộn lại để az
khi tăng lên ba
. Điều này không đặc biệt đáng ngạc nhiên.
$foo = "3d8";
echo "$foo\n";
$foo++;
echo "$foo\n";
$foo++;
echo "$foo\n";
$foo++;
echo "$foo\n";
( nhàn rỗi )
Điều này in ra:
3d8
3d9
3e0
4
Chào mừng bạn đến sự nguy hiểm của các chuyển đổi ngầm định và các toán tử hoạt động khác nhau trên cùng một chuỗi. (Perl xử lý khối mã đó một chút khác biệt - nó quyết định rằng "3d8"
khi ++
toán tử được áp dụng là một giá trị số từ đầu và chuyển sang 4
ngay ( ideone ) - hành vi này được mô tả tốt trong perlop: Tự động tăng và Tự động giảm )
Bây giờ, tại sao một ngôn ngữ làm một cái gì đó theo cách này và cách khác làm theo cách khác theo suy nghĩ thiết kế của các nhà thiết kế. Triết lý của Perl là có nhiều hơn một cách để làm điều đó - và tôi có thể nghĩ ra một số cách để thực hiện một số thao tác này. Mặt khác, Python có một triết lý được mô tả trong PEP 20 - Zen of Python nói (trong số những thứ khác): "Nên có một - và tốt nhất là chỉ có một cách rõ ràng để làm điều đó."
Những khác biệt thiết kế đã dẫn đến các ngôn ngữ khác nhau. Có một cách để lấy độ dài của một số trong Python. Chuyển đổi ngầm đi ngược lại triết lý này.
Đọc liên quan: Tại sao Ruby không chuyển đổi ngầm định Fixnum thành Chuỗi?
perl -e 'print length(100);'
bản in 3.