- Динамическая типизация
-
Типизация данных Типобезопасность
Вывод типов
Динамическая типизация
Статическая типизация
Строгая типизация
Мягкая типизация
Зависимые типы
Утиная типизацияДинами́ческая типиза́ция — приём, широко используемый в языках программирования и языках спецификации, при котором переменная связывается с типом в момент присваивания значения, а не в момент объявления переменной. Таким образом, в различных участках программы одна и та же переменная может принимать значения разных типов. Примеры языков, где есть динамическая типизация — Smalltalk, Python, Objective-C, Ruby, PHP, Perl, JavaScript, Lisp, xBase,QtScript.
Противоположный приём — статическая типизация.
В некоторых языках с динамической типизацией стоит проблема сравнения величин, так, например, PHP имеет операции сравнения «
==», «!=» и «===», «!==», где вторая пара операций сравнивает и значения, и типы переменных. Операция «===» даёт true только при полном совпадении, в отличие от «==», который считает верным такое выражение: (1=="1"). Стоит отметить, что это проблема не динамической типизации в целом, а конкретных языков программирования.Содержание
Преимущества
- Минимум дополнительных строк: переменные надо либо просто объявить без указания типа (JavaScript), либо вообще объявлять не нужно (Бейсик) или не обязательно (PHP).
- Соответственно, упрощается написание простых программ.
- Повышается гибкость языка. Например, только динамический язык может иметь функцию
eval(), вычисляющую значение произвольного выражения. - Ускоряет работу компилятора — а значит, производственный цикл «написать-проверить».
- Автоматически даёт языку элементы метапрограммирования и интроспекции.
- Другими словами: когда программист пишет функцию «отсортировать массив», функция сразу начинает работать для массива чисел, массива строк, массива объектов (метапрограммирование). Чтобы определить, возможна ли операция
x.length, среде выполнения нужно знать, какого типа переменнаяxи есть ли у неё полеlength; если подобные запросы может делать и сама программа, это и есть интроспекция.
- Другими словами: когда программист пишет функцию «отсортировать массив», функция сразу начинает работать для массива чисел, массива строк, массива объектов (метапрограммирование). Чтобы определить, возможна ли операция
- Упрощается работа прикладного программиста с СУБД, которые принципиально возвращают информацию в «динамически типизированном» виде. Поэтому динамические языки ценны, например, для программирования веб-служб.
- Иногда требуется работать с данными переменного типа. Например, функция поиска подстроки возвращает позицию найденного символа (число) или маркер «не найдено». В PHP этот маркер — булевское
false. В статических языках это особая константа (0 в Паскале,std::string::nposв C++).
Недостатки
- Статическая типизация позволяет уже при компиляции заметить простые ошибки «по недосмотру». Для динамической типизации требуется как минимум выполнить данный участок кода.
- Особенно коварны в динамическом языке программирования опечатки: разработчик может несколько раз просмотреть неработающий код и ничего не увидеть, пока наконец не найдёт набранный с ошибкой идентификатор.
- В объектно-ориентированных языках не действует либо действует с ограничениями автодополнение: трудно или невозможно понять, к какому типу относится переменная, и вывести набор её полей и методов.
- Для написания сложного кода нужна особая культура программирования: венгерская нотация, юнит-тестирование и т. д. В статических языках, вообще-то, тоже, но намного в меньшей степени.
- Интерфейсная часть модуля (описания типов, заголовки процедур и т. д. — то, что соответствует
interface-секции в Паскале и h-файлу в Си) в статическом языке сама по себе является существенной частью документации — а при удачной архитектуре модуля вообще позволяет обойтись без документирования. - Низкая скорость, связанная с динамической проверкой типа. К тому же большинство языков с динамической типизацией интерпретируемые, а не компилируемые.
Примеры
PHP
<html><head><title>test</title></head> <body> <?php $res = "string1"; echo $res.'<br />'; // выводит "string1" $res = 1; echo $res.'<br />'; // выводит "1" $res += 2; echo $res.'<br />'; // выводит "3" $res += "string2"; echo $res.'<br />'; // выводит "3string2" ?> </body> </html>
JavaScript
<html><head><title>test</title></head> <body> <script type="text/javascript"> function DoTest(obj) { var res = "string1"; alert(res); // выводит «string1» res = 1; alert(res); // выводит «1» res += 2; alert(res); // выводит «3» res += 'string2'; alert(res); // выводит «3string2» } </script> <a href="#" onClick="DoTest()">Click to test</a> </body></html>
Object Pascal
program Project2; {$APPTYPE CONSOLE} Uses SysUtils; Var V1, V2: Variant; begin V1 := 'string1'; WriteLn(V1); // выводит "string1" V2 := 1; WriteLn(V2); // выводит "1" Inc(V2,2); WriteLn(V2); // выводит "3" WriteLn(V2,'string2'); // выводит "3string2" end.
Object Pascal: Другие способы использования динамической типизации
procedure TForm1.Myproc(Obj: TObject); begin If (Obj is TButton) then (Obj as TButton).Click; end; function Something (A: array of const) begin // ... end; {Вызов: } Something ( [5,'Hello',3.14159, True, TForm] ); procedure TForm1.DisplayValue(const AValue: TValue); begin Memo1.Lines.Append(AValue.ToString); end; procedure TForm1.btn1Click(Sender: TObject); var list: TStrings; begin list := TStringList.Create(); list.Text := 'Foo'; try DisplayValue(list); DisplayValue(list.Count); DisplayValue(list.Capacity * 8.964); DisplayValue(list is TStringList); DisplayValue(list.Text); finally list.Free; end; end; {Вывод: (TStringList @ 0166E460) 1 35,856 True Foo }
См. также
- Типизация
- Строгая типизация
- Слабая типизация
- Статическая типизация
- Приведение типа
- Вывод типов
- Динамический язык программирования
Ссылки
Для улучшения этой статьи желательно?: - Найти и оформить в виде сносок ссылки на авторитетные источники, подтверждающие написанное.
- Проставив сноски, внести более точные указания на источники.
Категории:- Типы данных
- Определение соответствия
Wikimedia Foundation. 2010.