Intereting Posts
Как сделать аргумент по умолчанию? Загрузка изображения в правильное положение в режиме ресайклера Могу ли я запустить Android Studio 3.0 без Kotlin? Как вводить нестатические, по требованию NativeModules в React Native Android? Не удается разрешить символ @ReadOnly и @Mutable в компиляции Kotlin 1.1.0 Okhttp3-запрос, возвращающий пустой ответ, а также разные заголовки, чем Postman Android studio3.0 kotlin classNotFoundException Рекурсивный вызов по ленивому значению с использованием LiveData и ObserveForever AndroidStudio / Kotlin – Неразрешенная ссылка: ReadWriteProperty – Kotlin версия 1.0.0-beta-1038 Котировка класса данных Котлина с измененным значением var Делегирование недвижимости, измененное изменчивой картой Каков самый простой способ получить потокобезопасное свойство в Котлин? Смарт-литье и сравнение внутри Когда выражение после «есть» проверка типа Сбой сборки при использовании «kotlin-kapt» с Realm Библиотека Glide java.lang.NoClassDefFoundError

почему kotlin использует === сравнить примитивный тип, равный друг другу, если они имеют одинаковое значение

val hello1 = "hello" val hello2 = "hello" printf(hello1 === hello2) 

зачем печатать правду?

Я думаю, у kotlin есть примитивный пул типов (или что-то в этом роде). Если значение равно равенству, указатель указывает на одно и то же место. Я не уверен.

Равенство в Котлине

Я уже объяснил понимание равенства Котлина в этом ответе . Проще говоря:

  1. структурное равенство: == скомпилировано equals Java и ===

  2. Ссылочное равенство: === есть то, что == делает в Java: ссылки сравниваются друг с другом. Это правда, если сравнивать одни и те же объекты.

Как насчет строк как в вашем примере?

Строки отличаются тем, что они работают с так называемым пулом константных строк . Например, даже в Java для обоих сравнений true следующее:

  public static void main(String[] args) { String s = "prasad"; String s2 = "prasad"; System.out.println(s.equals(s2)); System.out.println(s == s2); } 

С другой стороны, этот фрагмент работает иначе, потому что создаются new строки:

 String foo = new String("hello"); String bar = new String("hello"); System.out.println(foo == bar); // prints 'false' 

Читайте об этом здесь: Что такое пул строк Java и как он «отличается от нового String (« s »)?

FYI: String s не примитивны.

строковый литерал всегда ссылается на тот же экземпляр класса String. Это связано с тем, что строковые литералы, или, в более общем смысле, строки, которые являются значениями константных выражений (§15.28), «интернированы», чтобы обмениваться уникальными экземплярами, используя метод String.intern.

Котлин просто повторяет тот же механизм. См. « Строковый литературный пул» набор ссылок на объект String, или набор литералов Листа и String String для дополнительных объяснений.

https://kotlinlang.org/docs/reference/equality.html

В Котлине существует два типа равенства:

  • Ссылочное равенство (две ссылки указывают на один и тот же объект);
  • Структурное равенство (проверка для equals ()).

Ссылочное равенство проверяется операцией === (и ее отрицательной копией !== ). a === b оценивает значение true тогда и только тогда, когда a и b указывают на один и тот же объект .

Структурное равенство проверяется операцией == (и ее отрицательной копией != ). По соглашению выражение, подобное a == b , переводится на: Таким образом, вы видите

 a?.equals(b) ?: (b === null) 

Итак, вы видите: == означает equals и === означает ссылочное равенство

Это означало бы, что

 val hello1 = "hello" val hello2 = "hello" printf(hello1 === hello2) 

является ссылочным сравнением, которое должно приводить к false . НО: Когда вы используете строковый литерал типа "hello" , используется кеш строки java (это оптимизация для сохранения памяти). Таким образом, вы получаете оба раза одну и ту же ссылку, и поэтому ссылочное равенство истинно.