Я новичок в Дарте. В документации говорится: «Чтобы проверить, представляют ли два объекта x и y одно и то же, используйте оператор ==. (В редких случаях, когда вам нужно знать, являются ли два объекта одним и тем же объектом, вместо этого используйте функцию идентичных() .)"
Итак, если ввести этот код:
var foo = 'bar';
var baz = 'bar';
print(identical(foo, baz));
Если я правильно понял, foo и bar не ссылаются на один и тот же объект. Таким образом, идентичный() должен возвращать false, не так ли? Но это не так, по крайней мере, в DartPad.
В чем проблема.
Для нескольких встроенных «литералов» вы всегда будете получать одинаковые true
для равных значений.
В этом случае foo
и bar
ссылаются на один и тот же объект.
Это потому, что компилятор канонизирует строковых литералов.
Спецификация требует, чтобы большинство констант были канонизированы. Если вы создадите const Duration(seconds: 1)
в двух местах, он станет объектом такой же. Целые, двойные и логические значения всегда канонизируются, независимо от того, константны они или нет (язык делает вид, что существует только один экземпляр для каждого значения).
Строки отличаются тем, что в спецификации не совсем ясно, нужно ли их канонизировать или нет, но строки постоянныйнужно должны быть канонизированы для констант, чтобы они имели смысл, и все компиляторы делают это.
Литерал — это постоянное выражение, поэтому строковые литералы всегда канонизированы. Это означает, что 'bar'
обозначает один и тот же объект независимо от того, где он встречается в вашем коде.
Если вы компилируете код в JavaScript, то все одинаковые строки также идентичны. Это связано с тем, что JavaScript не позволяет различить две строки с одинаковым содержимым. Компилятор Dart компилирует identical(a, b)
в JavaScript a === b
, и равные строки также ===
в JavaScript. Если код запускается на виртуальной машине, эти две строки, скорее всего, не будут идентичными.
Спасибо за ответ. Но если я создам строку по коду (например, используя простой список: var chars = ['b','a','r'];, то применяю тот же цикл к двум переменным: chars.forEach((item ) {foo += item;}); chars.forEach((item) {baz += item;}); "identical" снова возвращает true, хотя теперь это не литералы. Странно.