Thứ nhất, Perl không có các loại. Nó không phân biệt giữa các chuỗi và số (ở bên ngoài).
Hơn nữa, nó không tạo sự khác biệt giữa các số và chuỗi ở cấp này. ngữ cảnh số và ngữ cảnh chuỗi là vấn đề nếu bạn kiểm tra xem có gì lớn hơn hoặc nhỏ hơn. Xem xét việc này:
my $foo = 200;
my $bar = 99;
print $foo > $bar ? $foo : $bar;
Rõ ràng nó sẽ in 200
, vì 200 là số lượng lớn hơn 99.
my $foo = 200;
my $bar = 99;
print $foo gt $bar ? $foo : $bar;
Nhưng điều này sẽ in 99
, vì 9
là alphanumerically (như trong chuỗi) lớn hơn 2
. Nó so sánh số lượng các điểm mã cho các ký tự.
Nhưng nếu tất cả những gì bạn muốn làm là kiểm tra sự bất bình đẳng, toán tử ne
là phạt. Ngay cả khi bạn không chắc liệu có những thứ nào ngoài số trong đầu vào của bạn hay không.
foreach my $key (keys(%$hash1)) {
if ($hash1->{$key} ne $hash2->{$key}) {
print($key);
}
}
eq
(và ne
) là đủ thông minh để xem nếu một số bước đầu đã được một chuỗi hoặc một số mà không có dấu ngoặc kép, bởi vì các đại diện nội bộ của những người khác.
Cảnh báo, chi tiết kỹ thuật phía trước.
Giá trị vô hướng được lưu trong _SV_s. Những điều khoản này có thể chứa những thứ khác nhau. Có một loại nội bộ đặc biệt cho các số nguyên đơn giản được gọi là IV và cũng được gọi là PV cho chuỗi. Perl chuyển đổi nội bộ giữa hai thứ đó khi cần thiết khi bạn sử dụng các số bên trong các chuỗi hoặc ngược lại.
Bạn có thể nhận được một số thông tin gỡ lỗi về biểu diễn dữ liệu nội bộ với Dump
từ Devel::Peek.
use Devel::Peek;
Dump("01");
Dump(01);
Sản lượng này sẽ:
SV = PV(0x19560d0) at 0x19327d0
REFCNT = 1
FLAGS = (POK,READONLY,IsCOW,pPOK)
PV = 0x1c94fd0 "01"\0
CUR = 2
LEN = 10
COW_REFCNT = 0
SV = IV(0x19739b0) at 0x19739c0
REFCNT = 1
FLAGS = (IOK,READONLY,pIOK)
IV = 1
Như bạn có thể thấy, một trong những đầu tiên là một chuỗi, và điều thứ hai là một số. Nhưng nếu chúng ta làm điều này
print "01" eq 01;
không có đầu ra, vì 01
là một số nguyên và sẽ được chuyển đổi sang "1"
để so sánh.Vì số 0
của "01"
không bằng 1
, không có gì được in.
Nếu giá trị của cấu trúc dữ liệu phức tạp hơn, bạn cần phải đi bộ cấu trúc. Mỗi loại phần tử cần phải có xử lý riêng. Có thể có tham chiếu mảng, tham chiếu băm, tham chiếu vô hướng, vô hướng, tham chiếu glob, dualvars và cứ tiếp tục như vậy. Có thể có đối tượng mà bạn muốn đối xử đặc biệt.
Tôi khuyên bạn nên xem cách Test::Deep triển khai điều này. Nếu bạn quyết định sử dụng nó trong mã sản xuất (và không phải là một thử nghiệm đơn vị), bạn có thể sử dụng Test::Deep::NoTest.
Phần lớn phụ thuộc vào việc bạn muốn '" 1 "' và '" 01 "' vv để so sánh bằng hoặc không bằng nhau. – Borodin
@ Borodin đó là sự thật. Nhưng 'eq' quan tâm đến điều đó, bởi vì biểu diễn bên trong. Tôi nghĩ rằng nó biết rằng '" 1 "' là một SV nội bộ, và '1' là một IV. Xem ví dụ này: 'nói 01 eq 1; nói 01 eq "1"; nói "01" eq "1"; "01" eq 1; ' – simbabque
Có, nhưng quan điểm của tôi là OP có thể (hoặc có thể không) muốn' "1" 'thành * khớp *' "01" 'và, thực sự' "1000E-3" '. Có hai hành vi, và trong trường hợp của một * dualvar * kết quả có thể khác nhau. – Borodin