Из Википедии, бесплатной энциклопедии
  (Перенаправлено из маскировки имени )
Перейти к навигации Перейти к поиску

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

Обзор [ править ]

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

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

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

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

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

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

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

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

>>> number  =  99 >>> first_noun  =  " issues " >>> second_noun  =  "hound" >>> # Какие переменные использовать, решается во время выполнения >>> print ( f "Я получил { number } { first_noun }, но { second_noun } не один.» ) у меня 99 проблем , но собака не один. 

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

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

Маскировка имени [ править ]

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

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

Говорят, что внешняя переменная X затенена внутренней переменной X '.

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

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

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

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

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

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

класс  Point  { частный :  двойной  x ,  y ;public :  Point ( double  x ,  double  y )  {  // объявленные здесь x и y маскируют  частные setX ( x );  setY ( y );  } void  setX ( двойной  новый x )  {  x  =  newx ;  }  void  setY ( двойной  новый y )  {  y  =  newy ;  } }

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

класс  Point  { частный :  двойной  x ,  y ;общедоступные :  точка ( двойная  а ,  двойная  б )  {  setX ( а );  setY ( b );  } void  setX ( двойной  новый x )  {  x  =  newx ;  }  void  setY ( двойной  новый y )  {  y  =  newy ;  } }

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

См. Также [ править ]

  • Пространство имен (программирование)
  • Область применения (программирование)
  • Коллизия имен

Ссылки [ править ]

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