<<
>>

Динамическое связывание типов

При динамическом связывании оператор объявления переменной не содержит имени типа. Вместо этого тип переменной определяется при присвоении ей значения оператором присваивания. При выполнении оператора присваивания переменная из его левой части получает тип переменной, выражения или значения, находящегося в его правой части.

Такое присваивание может связать переменную с новым адресом и новой ячейкой памяти, потому что форматы хранения величин в разных типах отличаются друг от друга. Динамическое связывание постулирует: любой переменной может быть присвоено значение любого типа. Более того, во время выполнения программы тип переменной может меняться многократно. Важно понимать, что тип у переменной с динамически связанным типом имеет лишь временный характер.

226

Глава 8. Типизация данных

Если тип связан с переменной статически, то имя переменной навсегда привязано к этому типу.
Напротив, если тип связан с переменной динамически, то имя переменной лишь временно привязано к типу. На самом деле имена таких переменных никогда не ограничены типами. Более точно: имена могут быть связаны с переменными, а переменные могут быть связаны с типами.

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

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

До середины 1990-х годов самые популярные языки программирования повсеместно использовали статическое связывание типа, редким исключением были некоторые функциональные языки, такие как LISP. Однако с тех пор произошел существенный сдвиг в сторону динамического связывания типов. В языках Python, Ruby, JavaScript и PHP теперь принято динамическое связывание типа. Например, программа на языке JavaScript может содержать следующий оператор: list = [4.3, 8.2];

Независимо от предыдущего типа переменной list, в результате такого присваивания она превратится в одномерный массив из двух элементов, являющихся числами с плавающей точкой. Если же далее последует оператор list = 75;

то переменная list станет целочисленной скалярной переменной.

Возможность динамического связывания типа была введена в язык C# версии 2010 года. Включение в объявление переменной зарезервированного слова dynamic разрешает динамическое связывание типа, это показано в следующем примере: dynamic any;

Можно отметить некоторое сходство данного объявления с объявлением object any;

Объявления схожи в том, что переменной any может быть присвоено значение любого типа (даже типа object), как и для объявления с фиксированным типом object. Различие же заключается в исключении возможностей взаимодействия с фрагментами на таких динамически типизированных языках, как IronPython и IronRuby (.NET версий языков Python и Ruby соответственно). Тем не менее это полезно, если данные неизвестного типа поступили в программу из внешнего источника. Члены класса, свойства, параметры метода, возвращаемые методом величины и локальные переменные — все они могут быть объявлены динамичными.

В чисто объектно-ориентированных языках — например, Ruby — все переменные являются ссылками и не имеют типов, а все данные считаются объектами, и любая

Атрибуты переменной

227

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

В заключение еще раз обсудим недостатки динамического связывания типов. Прежде всего снижается надежность программ, поскольку возможности обнаружения ошибок много меньшие, чем у компилятора для языка со статическим связыванием типов. Динамическое связывание типов позволяет присвоить любой переменной значение любого типа. В этом случае неправильные типы на правой стороне оператора присваивания не будут распознаны как ошибки, вместо этого тип переменной-приемника изменится на этот неправильный тип. Допустим, что в конкретной программе на JavaScript имеются две скалярные числовые переменные а и b, а также массив m. Допустим также, что в программе должен быть оператор присваивания: a = b;

Вместо него был введен неправильный оператор: a = m;

В языке JavaScript (или любом другом языке с динамическим связыванием типов) интерпретатор ошибку не обнаружит. Тип переменной а просто будет изменен на тип массива. Поскольку при дальнейшем использовании переменной а ожидалось скалярное значение, результаты станут непредсказуемыми. В языке со статическим связыванием типов, таком как Java, компилятор обнаружит ошибку а = m, и программа не будет выполнена.

Отметим, что этот недостаток частично присутствует и в языках со статическим связыванием типов (Fortran, С и С++), которые в некоторых случаях автоматически приводят результат из правой части оператора присваивания к типу переменной из его левой части.

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

В языках с динамическим связыванием типов чаще всего используются интерпретаторы. У аппаратных средств компьютера нет команд, типы операндов которых неизвестны в период компиляции. Потому компилятор не может создавать машинные команды для выражения x + у, где типы x и у неизвестны в период компиляции. Чистая интерпретация, как правило, выполняется в 10 раз медленнее, чем эквивалентный машинный код. Конечно, если язык реализуется чистым интерпретатором, то время на выполнение динамического связывания типов скрыто и кажется более дешевым. С другой стороны, в языках со статическим связыванием типов обычно применяются компиляторы, так как программы на этих языках транслируются в очень эффективный машинный код.

228

Глава 8. Типизация данных

<< | >>

Еще по теме Динамическое связывание типов:

  1. Позитивное связывание
  2. Ограничение свободы движений (связывание, стягивание)
  3. Ограничение свободы движений (связывание, стягивание)
  4. СТЕРЕОТИП ДИНАМИЧЕСКИЙ
  5. ПСИХОЛОГИЯ ДИНАМИЧЕСКАЯ
  6. АНАЛИЗ КАУЗАЛЬНО-ДИНАМИЧЕСКИЙ
  7. Динамическая медитация
  8. В динамических методах
  9. ПСИХИКА: ПОНИМАНИЕ ДИНАМИЧЕСКОЕ
  10. Динамический смысл аспектов
  11. ПРОЦЕСС ПСИХИЧЕСКИЙ: ХАРАКТЕРИСТИКА ДИНАМИЧЕСКАЯ
  12. 46. Динамические процессы в малой группе
  13. ЛЕКЦИЯ 12 2.3. Динамические процессы городской жизни
  14. СОЦИОЛОГИЧЕСКИЙ АНАЛИЗ СЕМЬИ В ЕДИНСТВЕ СТРУКТУРНЫХ И ДИНАМИЧЕСКИХ КООРДИНАТ
  15. 13.4. Типовые следственные ситуации
  16. Статья 1111. Типовой лицензионный договор
  17. Таблица типов