Перейти к содержимому

Уроки · 68

Что такое идентификатор

В уроке «Идентификатор кружка» кольцо безошибочно находило ровно один кружок — тот, чей id совпадал с TARGET_ID. Это сработало только потому, что ни у каких двух кружков в списке id не совпадал. Разберёмся, что это за гарантия и откуда она берётся.

В прошлом уроке ID был u32, но дело не в самом типе. ID — это любое значение, которое у каждой вещи своё, непохожее на чужое: с тем же успехом это могла бы быть строка или что-то ещё. На практике чаще всего берут именно целые числа — они занимают мало места и сравнивать их между собой дешевле, чем, скажем, строки.

Уникальность — это правило, а не физический закон

Заголовок раздела «Уникальность — это правило, а не физический закон»

Координаты двух разных кружков вполне могут случайно совпасть — ничего страшного в этом нет, это просто два числа, x и y. А вот у индекса в списке одинаковых значений не бывает в принципе — circles[3] — это всегда ровно один элемент, два элемента под одним и тем же индексом лежать не могут, так уж устроен список.

С ID всё иначе. Ничто в Rust, ни в самом компьютере не мешает по ошибке выдать одному кружку тот же id, что и другому: это просто число, записанное в кортеже, как любое другое. Уникальность ID — не физический закон вроде невозможности двух элементов под одним индексом, а правило, которое мы сами для себя завели, когда решили раздавать ID растущим счётчиком. Rust не проверяет это за нас — если правило нарушится, никакой ошибки компиляции не будет.

А если нарушится — поиск по ID перестаёт работать так, как задуман. Если бы по ошибке два кружка получили одинаковый TARGET_ID, цикл наткнулся бы на первое совпадение и нарисовал кольцо вокруг него, а второй кружок с тем же ID так и остался бы без кольца, хотя подходил под условие ничуть не хуже первого. Разница с индексом в этом и есть: circles[TARGET_INDEX] не может случайно вернуть не тот элемент — а поиск по ID может, если уникальность перестала соблюдаться.

Имя человека может повторяться сколько угодно — в одной комнате может оказаться два тёзки, и это никого не удивляет. ID — наоборот: мы с самого начала договариваемся использовать его именно для того, чтобы отличать одно от другого, так что повторяться ему нельзя.

  • Идентификатор — это любое значение, уникальное для каждой вещи в своём наборе: число, строка, что угодно. Чаще всего — целое число, потому что оно компактнее и быстрее сравнивается.
  • Уникальность ID — это обязательство, которое соблюдает код, а не гарантия, которую даёт Rust или компьютер сам по себе.
  • Если это обязательство нарушить, поиск по ID перестаёт давать однозначный ответ — в отличие от индекса, где два элемента под одним номером лежать не могут в принципе.

Раз уникальность ID — это гарантия, на которую можно положиться (пока код её честно соблюдает), для поиска по ID подойдёт не только перебор списка, а структура, рассчитанная именно на уникальные ключи — об этом в уроке «HashMap».