stringtranslate.com

Разрешение имен (языки программирования)

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

Обзор

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

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

Статика против динамики

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

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

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

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

>>> number  =  99 >>> first_noun  =  "problems" >>> second_noun  =  "hound" >>> # Какие переменные использовать, решается во время выполнения >>> print ( f "I got { number } { first_noun } but a { second_noun } ain't one." ) У меня 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» в этом общем шаблоне:

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

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

Переименование Alpha для упрощения разрешения имен

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

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

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

В конструкторе Point переменные экземпляра x и y затеняются локальными переменными с тем же именем. Это может быть переименовано в альфа-версию:

класс Point { private : double x , y ;     public : Point ( double a , double b ) { setX ( a ); setY ( b ); }         void setX ( double newx ) { x = newx ; } void setY ( double newy ) { y = newy ; } }               

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

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

Ссылки

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