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

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

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

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

Solutions Collecting From Web of "почему 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 (это оптимизация для сохранения памяти). Таким образом, вы получаете оба раза одну и ту же ссылку, и поэтому ссылочное равенство истинно.