Kotlin-Функции расширения и типы платформ?

Я хочу добавить две функции расширения к ResultSet, которые получают значение как LocalDate.

fun ResultSet.getLocalDate(colName: String) = getDate(colName)?.toLocalDate()
fun ResultSet.getLocalDate(colIndex: Int) = getDate(colIndex)?.toLocalDate()

Проблема в том, что getDate() возвращает Date!, и, очевидно, я мог бы получить нулевую ошибку без вызова ?. перед toLocalDate(). Но тогда любой, кто использует это расширение, должен использовать результат как LocalDate?, а не LocalDate!.

Есть ли способ сохранить тип платформы для согласованности? И пусть пользователь функции расширения решает, разрешено ли ей быть обнуляемым или нет? Или я неправильно смотрю на это как на неудобство, а не на особенность?


person tmn    schedule 29.03.2016    source источник
comment
Я предполагаю, что это вызывает более широкий вопрос дизайна: если JDBC был написан с Kotlin, будет ли каждый геттер поля иметь значение NULL? Это может иметь смысл, поскольку библиотека понятия не имеет, является ли столбец в таблице обнуляемым или нет...   -  person tmn    schedule 29.03.2016


Ответы (1)


Посмотрите на это под другим углом: если бы вы могли заставить свои функции возвращать значение типа платформы LocalDate!, небезопасная обнуляемость Java распространилась бы на использование функций в вашем коде Kotlin: они бы возвращали null в любое время, возможно, неожиданно для вызывающей стороны, используя возвращаемое значение как ненулевое.

Kotlin, в свою очередь, null-safe и не позволит передать null молча туда, где это вызовет NPE. Вместо этого каждое значение либо передается как обнуляемое, либо проходит ненулевую проверку или утверждение.

Типы платформ не обозначаются в языка, это всего лишь способ справиться с небезопасной обнуляемостью Java (просто рассматривать все значения Java как обнуляемые не работает). Они предоставляют вам способ заявить, что вы верите, что этот вызов кода Java не вернет null: когда вы обрабатываете T! как T, генерируется утверждение для его проверки. В противном случае вы работаете с типом платформы T! как с нулевым T?.

Нулевая безопасность — один из ключевых моментов в разработке языка Kotlin, и она заставляет вас решать для каждого значения в вашем коде Kotlin, допускает ли оно значение NULL или нет.

У вас есть два варианта дизайна API:

  • Возвращайте ненулевое значение, проверяя возможность нулевого значения внутри вашей функции.
  • Возвращает значение, допускающее значение NULL, и, таким образом, предупреждает вызывающую сторону о возможном null

Однако, если функция имеет семантику, позволяющую вызывающей стороне предположить, что она не вернет null при некоторых условиях, вы можете создать функцию-оболочку, которая делает утверждение. Это осуществимо в сочетании с дополнительной логикой или откатом, иначе вряд ли будет более кратким, чем утверждение (!!) в месте вызова.

person hotkey    schedule 29.03.2016