Динамическая типизация

18-08-2023

Типизация данных

Типобезопасность
Вывод типов
Динамическая типизация
Статическая типизация
Строгая типизация
Мягкая типизация
Зависимые типы
Утиная типизация

Шаблон: ПросмотрОбсуждениеПравить

Динами́ческая типиза́ция — приём, широко используемый в языках программирования и языках спецификации, при котором переменная связывается с типом в момент присваивания значения, а не в момент объявления переменной. Таким образом, в различных участках программы одна и та же переменная может принимать значения разных типов. Примеры языков, где есть динамическая типизация — Smalltalk, Python, Objective-C, C#, Ruby, PHP, Perl, JavaScript, Lisp, xBase.

Противоположный приём — статическая типизация.

В некоторых языках с динамической типизацией стоит проблема сравнения величин, так, например, PHP имеет операции сравнения «==», «!=» и «===», «!==», где вторая пара операций сравнивает и значения, и типы переменных. Операция «===» даёт true только при полном совпадении, в отличие от «==», который считает верным такое выражение: (1=="1"). Стоит отметить, что это проблема не динамической типизации в целом, а конкретных языков программирования.

Содержание

Преимущества

  • Минимум дополнительных строк: переменные надо либо просто объявить без указания типа (JavaScript), либо вообще объявлять не нужно (Бейсик) или не обязательно (PHP).
  • Соответственно, упрощается написание простых программ.
  • Повышается гибкость языка. Например, только динамический язык может иметь функцию eval(), вычисляющую значение произвольного выражения.
  • Ускоряет работу компилятора — а значит, производственный цикл «написать-проверить».
  • Автоматически даёт языку элементы метапрограммирования и интроспекции.

Недостатки

  • Статическая типизация позволяет уже при компиляции заметить простые ошибки «по недосмотру». Для динамической типизации требуется как минимум выполнить данный участок кода.
    • Особенно коварны в динамическом языке программирования опечатки: разработчик может несколько раз просмотреть неработающий код и ничего не увидеть, пока наконец не найдёт набранный с ошибкой идентификатор.
  • В объектно-ориентированных языках не действует либо действует с ограничениями автодополнение: трудно или невозможно понять, к какому типу относится переменная, и вывести набор её полей и методов.
  • Для написания сложного кода нужна особая культура программирования: венгерская нотация, юнит-тестирование и т. д.
  • Интерфейсная часть модуля (описания типов, заголовки процедур и т. д. — то, что соответствует 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
}

См. также

Ссылки

  • Sitepoint: Introduction to Static and Dynamic Typing (англ.)
  • Лекция: Типизация


Динамическая типизация.

© 2011–2023 stamp-i-k.ru, Россия, Барнаул, ул. Анатолия 32, +7 (3852) 15-49-47