Почему и как типы с нулевым значением Int можно сравнивать для равенства, но нельзя сравнивать для большего / меньшего?

#android #kotlin #null

#Android #kotlin #null

Вопрос:

Извините за простой вопрос, но.. Почему Int / Long / Double и т. Д. Можно сравнивать с == внутри оператора if, но при попытке сравнения с > или < компилятор отказывается от этого?

Комментарии:

1. Я не уверен на 100%, но вы можете сравнить null == null , и он вернет true или null == 1 и вернет false. Но о чем вы думаете? null < 1 должно ли оно возвращать true или false?

2. Я вас понимаю, но откуда компилятор это знает? В соответствии с чем он решил, какой метод допустим, а какой нет?

3. a == b переведено на a?.equals(b) ?: (b === null) kotlinlang.org/docs/reference/operator-overloading.html#equals , но для операторов сравнения не очевидно, что мы должны делать, если есть объекты с нулевым значением

4. «Обратите внимание, что нет смысла оптимизировать ваш код при явном сравнении с null: a == null будет автоматически преобразован в a === null «. kotlinlang.org/docs/reference/equality.html

5. === означает ссылочное равенство, то есть буквально один и тот же объект в памяти, тогда == как просто означает is equal to , что это может быть один и тот же объект, или это могут быть два разных экземпляра, которые возвращают true for a.equals(b) . Насколько мне известно, существует только один экземпляр null anyway (вероятно, поэтому он переводится на === !)

Ответ №1:

Равенство, как и типы функций, является функцией языка, поэтому оно просто работает, чтобы использовать его для объекта с нулевым значением. Когда вы пытаетесь выполнить вызов функции в исходном коде, это просто приводит вас к Any.equals , хотя это не должно вызываться из nullable, если следовать правилам функций оператора.

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

Если бы вы хотели написать свою собственную функцию, которая работает с типами с нулевым значением, вы бы определили ее как функцию расширения с нулевым получателем. Например:

 fun MyClass?.doSomething() {
    if (this == null) {
        println("is null")
    } else {
        println("Hello from $this")
    }
}
 

Комментарии:

1. я не знал, что в объявлении функции я могу добавить знак вопроса. Итак, я могу добавить метод расширения king of: Int?.compareTo?