Привязка имени
В языках программирования привязка имен — это ассоциация сущностей (данных и/или кода) с идентификаторами . [1] идентификатор, привязанный к объекту, Говорят, что ссылается на этот объект. В машинных языках нет встроенного понятия идентификаторов, но привязка имени к объекту как услуга и нотация для программиста реализуются языками программирования. Привязка тесно связана с областью видимости , поскольку область видимости определяет, какие имена привязываются к каким объектам – в каких местах программного кода ( лексически ) и в каком из возможных путей выполнения ( временно ).
Использование идентификатора id в контексте, который устанавливает привязку для id называется связывающим (или определяющим) явлением. Во всех других случаях (например, в выражениях , присваиваниях и вызовах подпрограмм ) идентификатор обозначает то, с чем он связан; такие явления называются прикладными явлениями.
Время связывания
[ редактировать ]- Статическая привязка (или ранняя привязка ) — это привязка имени, выполняемая перед запуском программы. [2]
- Динамическая привязка (или поздняя привязка , или виртуальная привязка ) — это привязка имени, выполняемая во время работы программы. [2]
Примером статической привязки является прямой вызов функции C : функция, на которую ссылается идентификатор, не может изменяться во время выполнения.
Примером динамической привязки является динамическая диспетчеризация , например вызов виртуального метода C++ . Поскольку конкретный тип полиморфного объекта неизвестен до времени выполнения (как правило), выполняемая функция динамически привязывается. Возьмем, к примеру, следующий Java- код:
public void foo(java.util.List<String> list) {
list.add("bar");
}
List
это интерфейс , поэтому list
должен относиться к подтипу . его list
может ссылаться на LinkedList
, ArrayList
или какой-либо подтип другой List
. Метод, на который ссылается add
неизвестен до времени выполнения. В C, где нет динамической привязки, аналогичная цель может быть достигнута путем вызова функции, на которую указывает переменная или выражение типа указателя на функцию , значение которого неизвестно, пока оно не будет вычислено во время выполнения.
Пересвязывание и мутация
[ редактировать ]Повторное связывание не следует путать с мутацией или присвоением.
- Повторная привязка — это изменение ссылающегося идентификатора.
- Присваивание — это изменение (ссылочной) переменной.
- Мутация — это изменение объекта в памяти, на которое может ссылаться переменная или которое привязано к идентификатору.
Рассмотрим следующий код Java :
LinkedList<String> list;
list = new LinkedList<String>();
list.add("foo");
list = null;
{ LinkedList<Integer> list = new LinkedList<Integer>(); list.add(Integer(2)); }
Идентификатор list
привязан к переменной в первой строке; во втором — переменной присваивается объект (связанный список строк). Затем связанный список, на который ссылается переменная, мутируется, добавляя в список строку. Далее переменной присваивается константа null
. В последней строке идентификатор перепривязывается к области действия блока. Операции внутри блока получают доступ к новой переменной, а не к переменной, ранее привязанной к ней. list
.
Поздняя статика
[ редактировать ]Поздняя статическая привязка — это вариант привязки, промежуточный между статической и динамической привязкой. Рассмотрим следующий пример PHP :
class A
{
public static $word = "hello";
public static function hello() { print self::$word; }
}
class B extends A
{
public static $word = "bye";
}
B::hello();
В этом примере интерпретатор PHP связывает ключевое слово self
внутри A::hello()
в класс A
и поэтому вызов B::hello()
выдает строку «привет». Если семантика self::$word
был основан на позднем статическом связывании, то результатом было бы «пока».
Начиная с версии PHP 5.3, поддерживается позднее статическое связывание. [3] В частности, если self::$word
в приведенном выше примере были изменены на static::$word
как показано в следующем блоке, где ключевое слово static
будет привязан только во время выполнения, тогда результат вызова B::hello()
было бы «пока»:
class A
{
public static $word = "hello";
public static function hello() { print static::$word; }
}
class B extends A
{
public static $word = "bye";
}
B::hello();
См. также
[ редактировать ]- Таблица ветвей - метод передачи управления программой другой части программы.
- Абстрактный синтаксис высшего порядка - метод представления абстрактных синтаксических деревьев в языках с привязками переменных.
Ссылки
[ редактировать ]- ^ Microsoft (11 мая 2007 г.), Использование раннего связывания и позднего связывания в автоматизации , Microsoft , получено 11 мая 2009 г.
- ^ Jump up to: а б Системная и программная инженерия. Словарь ISO/IEC/IEEE 24765:2010(E) , IEEE, 15 декабря 2010 г.
- ^ «Поздние статические привязки» . Проверено 3 июля 2013 г.