loại không tương thích: int không thể được chuyển đổi sang boolean
Tôi quan tâm tại sao C không cho phép và java thì không. Do đó, tôi quan tâm đến hệ thống loại ngôn ngữ, đặc biệt là độ mạnh của nó.
Có hai phần cho câu hỏi của bạn:
Tại sao Java không chuyển đổi int
thành boolean
?
Điều này giúp Java có ý định rõ ràng nhất có thể. Nó rất tĩnh, rất "trong khuôn mặt của bạn" với hệ thống loại của nó. Những thứ được tự động nhập kiểu trong các ngôn ngữ khác thì không như vậy, trong Java. Bạn phải viết int a=(int)0.5
là tốt. Chuyển đổi float
để int
sẽ mất thông tin; tương tự như chuyển đổi int
sang boolean
và do đó sẽ dễ bị lỗi. Ngoài ra, họ sẽ phải chỉ định rất nhiều kết hợp. Chắc chắn, những điều này dường như là rõ ràng, nhưng họ có ý định sai lầm ở phía thận trọng.
Oh, và so sánh với các ngôn ngữ khác, Java là cực kỳ chính xác trong đặc tả của nó, như các bytecode không chỉ là một chi tiết thực hiện nội bộ. Họ sẽ phải chỉ định bất kỳ và tất cả các tương tác, chính xác. Cam kết rất lớn.
Tại sao if
không chấp nhận các loại khác hơn boolean
?
if
hoàn toàn có thể được định nghĩa là cho phép các loại khác hơn boolean
. Nó có thể có một định nghĩa cho biết những điều sau đây là tương đương:
true
int != 0
String
với .length>0
- Bất kỳ tham chiếu đối tượng nào khác không
null
(và không phải là Boolean
giá trị false
).
- Hoặc thậm chí: bất kỳ tham chiếu đối tượng nào khác không phải
null
và có phương thức Object.check_if
(được phát minh bởi tôi chỉ cho dịp này) trả về true
.
Họ đã không; không có nhu cầu thực sự, và họ muốn có nó mạnh mẽ, tĩnh, minh bạch, dễ đọc, v.v. càng tốt. Không có tính năng ngầm. Ngoài ra, việc triển khai sẽ khá phức tạp, tôi chắc chắn, phải kiểm tra từng giá trị cho tất cả các trường hợp có thể, do đó hiệu năng có thể cũng đóng một yếu tố nhỏ (Java đã từng bị chậm trễ trên các máy tính ngày đó; hãy nhớ rằng không có trình biên dịch JIT với các bản phát hành đầu tiên, ít nhất là không phải trên các máy tính tôi đã sử dụng sau đó).
Lý do sâu xa hơn
Một lý do sâu xa hơn có thể là thực tế là Java có các kiểu nguyên thủy của nó, do đó hệ thống kiểu của nó bị xé giữa các đối tượng và nguyên thủy. Có lẽ, nếu họ đã tránh những thứ đó, mọi thứ sẽ diễn ra theo một cách khác. Với các quy tắc được đưa ra trong phần trước, họ sẽ phải xác định tính trung thực của từng nguyên thủy một cách rõ ràng (vì người nguyên thủy không chia sẻ một siêu hạng, và không có định nghĩa rõ ràng null
cho nguyên thủy). Điều này sẽ biến thành một cơn ác mộng, nhanh chóng.
Triển vọng
Chà, và cuối cùng, có lẽ đó chỉ là sở thích của các nhà thiết kế ngôn ngữ. Mỗi ngôn ngữ dường như quay theo cách riêng của họ ở đó ...
Ví dụ, Ruby không có loại nguyên thủy. Tất cả mọi thứ, nghĩa đen là tất cả, là một đối tượng. Họ có một thời gian rất dễ dàng để đảm bảo rằng mọi đối tượng đều có một phương thức nhất định.
Ruby tìm kiếm sự trung thực trên tất cả các loại đối tượng bạn có thể ném vào nó. Thật thú vị, nó vẫn không có boolean
loại (vì nó không có nguyên thủy), và nó cũng không có Boolean
lớp. Nếu bạn hỏi giá trị của lớp đó là gì true
(có sẵn với true.class
), bạn sẽ nhận được TrueClass
. Lớp đó thực sự có các phương thức, cụ thể là 4 toán tử cho booleans ( | & ^ ==
). Ở đây, if
xem xét giá trị của nó falsey khi và chỉ khi nó là false
hoặc nil
( null
của Ruby). Mọi thứ khác đều đúng. Vì vậy, 0
hoặc ""
là cả hai sự thật.
Việc họ tạo ra một phương thức Object#truthy?
có thể được thực hiện cho bất kỳ lớp nào và trả lại một sự thật riêng lẻ là điều không quan trọng. Ví dụ, String#truthy?
có thể đã được triển khai là đúng với các chuỗi không trống hoặc không có gì. Họ đã không, mặc dù Ruby là phản đề của Java trong hầu hết các phòng ban (gõ vịt động với mixin, mở lại các lớp và tất cả những thứ đó).
Điều này có thể gây ngạc nhiên cho một lập trình viên Perl, người đã từng là $value <> 0 || length($value)>0 || defined($value)
sự thật. Và như vậy.
Nhập SQL với quy ước rằng null
bên trong bất kỳ biểu thức nào tự động làm cho nó sai, không có vấn đề gì. Vì vậy (null==null) = false
. Trong Ruby , (nil==nil) = true
. Thời gian hạnh phúc