Как уже отмечали другие, термины «строго типизированный» и «слабо типизированный» имеют так много разных значений, что нет единого ответа на ваш вопрос. Однако, поскольку вы специально упомянули Perl в своем вопросе, позвольте мне объяснить, в каком смысле Perl слабо типизирован.
Дело в том, что в Perl нет такой вещи как «целочисленная переменная», «переменная с плавающей запятой», «строковая переменная» или «логическая переменная». На самом деле, насколько может (обычно) пользователь может сказать, нет даже целочисленных, плавающих, строковых или логических значений : все, что у вас есть, - это «скаляры», которые представляют собой все эти вещи одновременно. Так что вы можете, например, написать:
$foo = "123" + "456"; # $foo = 579
$bar = substr($foo, 2, 1); # $bar = 9
$bar .= " lives"; # $bar = "9 lives"
$foo -= $bar; # $foo = 579 - 9 = 570
Конечно, как вы правильно заметили, все это можно рассматривать как просто приведение типов. Но дело в том, что в Perl типы всегда принудительно приводятся . На самом деле, пользователю довольно сложно определить, каким может быть внутренний «тип» переменной: в строке 2 в моем примере выше, спрашивать, является ли значение $bar
строкой "9"
или числом, 9
в значительной степени бессмысленно, поскольку Что касается Perl, это одно и то же . Действительно, для скаляра Perl даже возможно иметь одновременно строковое и числовое значение, как, например, для$foo
после строки 2 выше.
Обратная сторона всего этого заключается в том, что, поскольку переменные Perl нетипизированы (или, скорее, не предоставляют пользователю свой внутренний тип), операторы не могут быть перегружены, чтобы выполнять разные действия для разных типов аргументов; Вы не можете просто сказать «этот оператор будет делать X для чисел и Y для строк», потому что оператор не может (не будет) определять, какие значения являются его аргументами.
Таким образом, например, Perl имеет и нуждается как в числовом операторе сложения ( +
), так и в операторе конкатенации строк ( .
): как вы видели выше, совершенно нормально добавлять строки ( "1" + "2" == "3"
) или объединять числа ( 1 . 2 == 12
). Аналогично, числовые операторы сравнения ==
, !=
, <
, >
, <=
, >=
и <=>
сравнивать числовые значения своих аргументов, а операторы сравнения строк eq
, ne
, lt
, gt
, le
, ge
и cmp
сравнить их лексикографически как строки. Так 2 < 10
, но 2 gt 10
(но "02" lt 10
, пока "02" == 2
). (Обратите внимание, что некоторые другие языки, такие как JavaScript, попробуйте использовать Perl-подобную слабую типизацию во времятакже делает перегрузку оператора. Это часто приводит к уродству, например к потере ассоциативности +
.)
(Недостаток мази заключается в том, что по историческим причинам в Perl 5 есть несколько угловых случаев, например, побитовые логические операторы, поведение которых зависит от внутреннего представления их аргументов. Обычно это считается досадным недостатком дизайна, поскольку внутреннее представление может измениться по удивительным причинам, и поэтому предсказать, что эти операторы делают в данной ситуации, может быть сложно.)
Все , что сказал, можно утверждать , что Perl действительно есть сильные типы; они просто не те типы, которые вы могли бы ожидать. В частности, в дополнение к рассмотренному выше типу «скаляр» Perl также имеет два структурированных типа: «массив» и «хеш». Это очень отличается от скаляров, до точки , где переменный Perl имеют различные сигил , указывающие их тип ( $
для скаляров, @
для массивов, %
для хешей) 1 . Там есть правила принуждения между этими типами, так что вы можете написать , например %foo = @bar
, но многие из них являются весьма потерями, например, $foo = @bar
присваивает длину массива @bar
в$foo
, а не его содержание. (Также есть несколько других странных типов, таких как typeglobs и дескрипторы ввода / вывода, которые вы не часто видите открытыми.)
Кроме того, небольшим недостатком в этом хорошем дизайне является наличие ссылочных типов, которые являются особым видом скаляров (и которые можно отличить от обычных скаляров, используя ref
оператор). Можно использовать ссылки в качестве обычных скаляров, но их строковые / числовые значения не особенно полезны, и они имеют тенденцию терять свою специальную ссылку, если вы изменяете их, используя обычные скалярные операции. Кроме того, любая переменная Perl 2 может быть парадигмой. Общее мнение таково: если вы проверяете класс объекта в Perl, вы делаете что-то не так.bless
преобразована в класс, превращая ее в объект этого класса; система классов OO в Perl является несколько ортогональной к описанной выше системе примитивного типа (или отсутствия типа), хотя она также является "слабой" в смысле следования типу утки
1 На самом деле, символ обозначает тип доступного значения, так что, например, @foo
обозначается первый скаляр в массиве $foo[0]
. Смотрите perlfaq4 для более подробной информации.
2 Объекты в Perl (обычно) доступны через ссылки на них, но на самом деле редактируется bless
переменная (возможно, анонимная), на которую указывает ссылка. Однако благословение действительно является свойством переменной, а не ее значения, так что, например, присвоение фактической благословенной переменной другой дает вам ее неглубокую, необдуманную копию. Смотрите perlobj для более подробной информации.