Разрешение имен (языки программирования) - Name resolution (programming languages)

В языки программирования, разрешение имени - это разрешение токенов внутри программных выражений на предполагаемые программные компоненты.

Обзор

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

Сложность этих алгоритмов зависит от сложности языка. Например, разрешение имени в язык ассемблера обычно включает только один простой поиск в таблице, а разрешение имени в C ++ чрезвычайно сложен, поскольку включает в себя:

  • пространства имен, которые позволяют идентификатору иметь разные значения в зависимости от связанного с ним пространства имен;
  • объемы, которые позволяют идентификатору иметь разное значение на разных уровнях области действия и включают в себя различные правила переопределения и скрытия области. На самом базовом уровне разрешение имен обычно пытается найти привязка в наименьшей охватывающей области видимости, так что, например, локальные переменные заменяют глобальные переменные; это называется слежка.
  • правила видимости, которые определяют, будут ли идентификаторы из определенных пространств имен или областей видны из текущего контекста;
  • перегрузка, что позволяет идентификатору иметь разные значения в зависимости от того, как он используется, даже в одном пространстве имен или области действия;
  • доступность, который определяет, действительно ли идентификаторы из видимой в противном случае области видимости доступны и участвуют в процессе разрешения имен.

Статический против динамического

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

Довольно распространенное заблуждение состоит в том, что динамическая типизация подразумевает динамическое разрешение имен. Например, Erlang динамически типизирован, но имеет статическое разрешение имен. Однако статическая типизация подразумевает статическое разрешение имен.

Статическое разрешение имен улавливает во время компиляции использование переменных, которые не входят в область видимости; предотвращение ошибок программиста. Языки с динамическим разрешением осциллографа жертвуют этой безопасностью ради большей гибкости; они обычно могут устанавливать и получать переменные в одной и той же области во время выполнения.

Например, в Python интерактивный REPL:

>>> номер = 99>>> first_noun = "проблемы">>> second_noun = "гончая">>> # Какие переменные использовать, решается во время выполнения>>> Распечатать(ж"Я получил {номер}{first_noun} но {second_noun} не один ".)У меня 99 проблем, но с собакой нет.

Однако сообщество Python не рекомендует полагаться на динамическое разрешение имен в коде.[1][2] Эта функция также может быть удалена в более поздней версии Python.[3]

Примеры языков, использующих статическое разрешение имен, включают C, C ++, E, Erlang, Haskell, Ява, Паскаль, Схема, и Болтовня. Примеры языков, использующих динамическое разрешение имен, включают некоторые Лисп диалекты, Perl, PHP, Python, REBOL, и Tcl.

Маскировка имени

Маскировка возникает, когда один и тот же идентификатор используется для разных сущностей в перекрывающихся лексических областях. На уровне переменных (а не имен) это известно как переменное затенение. Идентификатор I '(для переменной X') маскирует идентификатор I (для переменной X), когда выполняются два условия.

  1. У меня то же имя, что и у меня
  2. I 'определяется в области видимости, которая является подмножеством области действия I

Внешняя переменная X называется затененный внутренней переменной X '.

Например, параметр «foo» затеняет локальную переменную «foo» в этом общем шаблоне:

частный int фу;  // Имя "foo" объявлено во внешней области видимостиобщественный пустота setFoo(int фу) {  // Имя "foo" объявляется во внутренней области видимости и является локальным для функции.    это.фу = фу;  // Поскольку "foo" будет сначала найден (и разрешен) в '' самой внутренней '' области,                     // чтобы успешно перезаписать сохраненное значение атрибута "foo"                     // с новым значением входящего параметра "foo" проводится различие                     // между this.foo (атрибут объекта) и foo (параметр функции). }общественный int getFoo() {    возвращаться фу;}

Маскировка имени может вызвать осложнения при перегрузке функций, из-за того, что перегрузка не происходит в областях на некоторых языках, особенно в C ++, что требует повторного объявления или явного импорта всех перегруженных функций в заданное пространство имен.

Альфа-переименование для упрощения разрешения имен

В языках программирования с лексическая область видимости это не отражать над именами переменных, α-преобразование (или α-переименование) можно использовать, чтобы упростить разрешение имен путем поиска подстановки, которая гарантирует, что имя переменной маски другое имя в содержащей его области. статический анализ кода проще, поскольку только альфа-переименовщик должен понимать правила области видимости языка.

Например, в этом коде:

учебный класс Точка {частный:  двойной Икс, у;общественный:  Точка(двойной Икс, двойной у) {  // объявленные здесь x и y маскируют частные    setX(Икс);    setY(у);  }  пустота setX(двойной Newx) { Икс = Newx; }  пустота setY(двойной новый) { у = новый; }}

в пределах Точка конструктор, переменные класса Икс и у находятся затененный одноименными локальными переменными. Это может быть переименовано в альфа-формате:

учебный класс Точка {частный:  двойной Икс, у;общественный:  Точка(двойной а, двойной б) {    setX(а);    setY(б);  }  пустота setX(двойной Newx) { Икс = Newx; }  пустота setY(двойной новый) { у = новый; }}

В новой версии нет маскировки, поэтому сразу видно, какое использование соответствует каким объявлениям.

Смотрите также

Рекомендации

  1. ^ "[Python-Ideas] служебная функция str.format". 9 мая 2009 года. Получено 2011-01-23.
  2. ^ «8.6. Форматирование строк на основе словаря». diveintopython.org. Марк Пилигрим. Получено 2011-01-23.
  3. ^ «9. Классы - документация Python». Получено 2019-07-24. Важно понимать, что области видимости определяются текстуально: глобальная область видимости функции, определенной в модуле, является пространством имен этого модуля, независимо от того, откуда и под каким псевдонимом вызывается функция. С другой стороны, фактический поиск имен выполняется динамически во время выполнения - однако определение языка развивается в сторону статического разрешения имен во время «компиляции», поэтому не полагайтесь на динамическое разрешение имен! (Фактически, локальные переменные уже определены статически.)