несумісні типи: int не може бути перетворений у логічний
Мене цікавить, чому C це дозволяє, а Java ні. Тому мене цікавить система типу мови, зокрема її міцність.
До вашого питання є дві частини:
Чому Java не конвертувати int
в boolean
?
Це зводиться до того, що Java має бути максимально чітким. Це дуже статично, дуже "в обличчя" зі своєю системою типів. Речі, які автоматично передаються на іншій мові, на Java не такі. Ви також повинні писати int a=(int)0.5
. Перетворення float
на int
втрачає інформацію; такий же, як перетворення int
в boolean
і, таким чином, буде схильним до помилок. Крім того, їм довелося б вказати багато комбінацій. Звичайно, такі речі здаються очевидними, але вони мали намір помилитися на стороні обережності.
О, і порівняно з іншими мовами, Java була надзвичайно точною у своїй специфікації, оскільки байт-код був не просто внутрішньою деталлю реалізації. Вони повинні були б точно вказати будь-які взаємодії. Величезне починання.
Чому if
не приймає інші типи, ніж boolean
?
if
цілком можна було б визначити, щоб дозволити інші типи, ніж boolean
. Він може мати визначення, яке говорить про те, що таке рівнозначне:
true
int != 0
String
з .length>0
- Будь-яка інша посилання на об'єкт, яка не є
null
(а не має Boolean
значення false
).
- Або навіть: будь-яка інша посилання на об'єкт, яка не є
null
і чий метод Object.check_if
(придуманий мною саме для цього випадку) повертає true
.
Вони не зробили; реальної потреби в цьому не було, і вони хотіли, щоб це було якомога міцнішим, статичним, прозорим, легким для читання тощо. Без неявних ознак. Крім того, реалізація була б досить складною, я впевнений, що потрібно перевіряти кожне значення для всіх можливих випадків, тому продуктивність, можливо, також відігравала невеликий фактор (Java раніше була слоухау на комп’ютерах того дня; пам’ятайте, що там не було компіляторів JIT з першими випусками, принаймні, не на комп’ютерах, якими я користувався тоді).
Більш глибока причина
Більш глибокою причиною може бути той факт, що у Java є свої примітивні типи, отже, її система типів розбита між об'єктами та примітивами. Можливо, якби вони цього уникали, то все вийшло б інакше. З правилами, наведеними в попередньому розділі, вони повинні були б чітко визначити правдивість кожного примітиву (оскільки примітиви не мають суперкласу, і null
для примітивів немає чітко визначеного ). Це швидко перетвориться на кошмар.
Прогноз
Ну, і врешті-решт, можливо, це просто вподобання мовних дизайнерів. Кожна мова, здається, крутиться там по-своєму ...
Наприклад, у Рубі немає примітивних типів. Все, буквально все, є об’єктом. Вони дуже просто переконуються, що кожен об'єкт має певний метод.
Рубі все-таки шукає правдивість на всіх видах предметів, на які можна кинути. Цікаво, що він досі не має boolean
типу (бо не має примітивів), іBoolean
класу він також не має . Якщо ви запитаєте, який клас true
має значення (зручно доступне true.class
), ви отримуєте TrueClass
. Цей клас насправді має методи, а саме 4 оператори для booleans ( | & ^ ==
). Тут if
враховується його значення фальси, якщо і тільки якщо воно є false
або nil
( null
Рубі). Все інше правда. Отже, 0
або ""
обидва вірні.
Для них було б тривіально створити метод, Object#truthy?
який можна було б реалізувати для будь-якого класу та повернути індивідуальну правдивість. Наприклад, String#truthy?
могло б бути реалізовано так, що це стосується не порожніх рядків чи чогось іншого. Вони цього не зробили, навіть незважаючи на те, що Рубі - це антитеза Java у більшості департаментів (динамічне введення качок з міксином, повторне відкриття класів та все таке).
Що може дивувати програміста Perl, який звик $value <> 0 || length($value)>0 || defined($value)
бути правдивим. І так далі.
Введіть SQL з його умовою, що null
всередині будь-якого виразу автоматично робиться помилковим, незважаючи ні на що. Отже (null==null) = false
. В Ruby (nil==nil) = true
. Щасливі часи.