В чем разница между строго типизированным языком и статически типизированным языком?

кроме того, означает ли одно другое?

8 ответов


в чем разница между строго типизированным языком и статически типизированным языком?

статически типизированный язык имеет систему типов, которая проверяется во время компиляции реализацией (компилятором или интерпретатором). Проверка типа отклоняет некоторые программы, и программы, которые проходят проверку, обычно имеют некоторые гарантии; например, компилятор гарантирует не использовать целочисленные арифметические инструкции с плавающей запятой числа.

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

статический против динамических

противоположностью статически типизированного является "динамически типизированный", что означает это

  1. значения, используемые во время выполнения, классифицируются по типам.
  2. существуют ограничения на использование таких значений.
  3. когда эти ограничения нарушаются, нарушение сообщается как ошибка (динамического) типа.

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

сильный против слабого

противоположностью " строго типизированного "является" слабо типизированный", что означает, что вы можете работать с системой типов. C, как известно, слабо типизирован, потому что любой тип указателя преобразуется в любой другой тип указателя просто путем приведения. Паскаль должен был быть строго напечатан, но надзор в дизайне (untagged variant records) ввел лазейку в систему типов, поэтому технически она слабо типизирована. Примеры действительно строго типизированных языков включают CLU, Standard ML и Haskell. Стандарт ML фактически претерпел несколько изменений, чтобы удалить лазейки в системе типов, которые были обнаружены после того, как язык был широко развернут.

что здесь происходит?

в целом, оказывается, не так уж полезно говорить о " сильных" и "слабый". Имеет ли система типов лазейку, менее важно, чем точное количество и характер лазеек, насколько они могут возникнуть на практике и каковы последствия использования лазейки. На практике, лучше всего вообще избегать терминов "сильный" и "слабый", потому что

  • любители часто объединяют их с "статическими"и " динамическими".

  • по-видимому," слабая типизация " используется некоторыми людьми говорить об относительной распространенности или отсутствии неявных преобразований.

  • профессионалы не могут договориться о том, что именно означают эти термины.

  • в целом, вы вряд ли информировать или просвещать свою аудиторию.

печальная правда заключается в том, что когда дело доходит до систем типов,"сильный" и "слабый" не имеют общепризнанного технического значения. если вы хотите обсудить относительную прочность типа системы, лучше обсудить, какие именно гарантии предоставляются, а какие нет. Например, хороший вопрос: "гарантируется ли, что каждое значение данного типа (или класса) было создано путем вызова одного из конструкторов этого типа?- В С ответ-нет. В CLU, F# и Haskell это да. Для C++ я не уверен-я хотел бы знать.

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

подразумевает ли одно другое?

на педантичном уровне, нет, потому что слово "сильный" на самом деле ничего не значит. Но на практике люди почти всегда делают одно из двух:--2-->

  • они (неправильно) используют "сильный" и "слабый", чтобы означать "статический" и "динамический", и в этом случае они (неправильно) используют "строго типизированный" и "статически типизированный" взаимозаменяемо.

  • они используют "сильный" и "слабый" для сравнения свойств систем статического типа. Очень редко можно услышать, как кто-то говорит о "сильном" или " слабом" система динамического типа. За исключением FORTH, который на самом деле не имеет никакой системы типов, я не могу думать о динамически типизированном языке, где система типов может быть разрушена. По определению, эти проверки bulit в механизм выполнения, и каждая операция проверяется на здравомыслие перед выполнением.

в любом случае, если человек называет язык "строго типизированным", этот человек, скорее всего, будет говорить о статически типизированном язык.


это часто неправильно понимают, поэтому позвольте мне прояснить это.

Статический / Динамический Ввод

статическая типизация где тип привязан к переменная. Типы проверяются во время компиляции.

динамическая типизация где тип привязан к стоимостью. Типы проверяются во время выполнения.

так, в Java например:

String s = "abcd";

s будет "вечно" быть String. В течение своей жизни он может указывать на разные Strings (с s является ссылкой на Java). У него может быть null значение, но оно никогда не будет ссылаться на Integer или List. Это статическая печать.

в PHP:

$s = "abcd";          // $s is a string
$s = 123;             // $s is now an integer
$s = array(1, 2, 3);  // $s is now an array
$s = new DOMDocument; // $s is an instance of the DOMDocument class

это динамическая типизация.

Сильный / Слабый Набрав

(Edit alert!)

строгой типизации это фраза без общепринятого значения. Большинство программистов, использующих этот термин это означает, что существует дисциплина типа, которая применяется компилятором. Например, CLU имеет сильную систему типов, которая не позволяет клиентскому коду создавать значение абстрактного типа, кроме как с помощью конструкторов, предоставляемых типом. C имеет несколько сильную систему типов, но ее можно "подорвать" до некоторой степени, потому что программа всегда может привести значение одного типа указателя к значению другого типа указателя. Так, например, в C вы можете взять a значение, возвращаемое malloc() и весело бросил его в FILE*, и компилятор не будет пытаться остановить вас-или даже предупредить вас, что вы не делаете ничего такого.

(в исходном ответе говорилось что-то о значении "не меняется тип во время выполнения". Я знал многих языковых дизайнеров и авторов компиляторов и не знал одного, который говорил о значениях, изменяющих тип во время выполнения, за исключением, возможно, некоторых очень продвинутых исследований в системах типов, где это известно как " сильное обновление проблема.")

слабая типизация означает, что компилятор не применяет дисковую линию ввода, или, возможно, что принудительное исполнение может быть легко свернуто.

оригинал этого ответа объединил слабую типизацию с неявное преобразование (иногда также называемую "скрытую рекламу"). Например, в Java:

String s = "abc" + 123; // "abc123";

это код является примером неявного продвижения: 123 неявно преобразуется в строку перед сцеплено с "abc". Можно утверждать, что компилятор Java переписывает этот код как:

String s = "abc" + new Integer(123).toString();

рассмотрим классический PHP "начинается с" Проблема:

if (strpos('abcdef', 'abc') == false) {
  // not found
}

ошибка здесь в том, что strpos() возвращает индекс совпадения, равный 0. 0 принуждается к логическому false и таким образом, состояние-это правда. Решение заключается в использовании === вместо == чтобы избежать неявного преобразования.

этот пример иллюстрирует сочетание неявное преобразование и динамическая типизация могут привести программистов в заблуждение.

сравните это с Ruby:

val = "abc" + 123

что является ошибкой времени выполнения, потому что в Ruby объект 123 составляет не неявно преобразуется только потому, что он передается в + метод. В Ruby программист должен сделать преобразование явно:

val = "abc" + 123.to_s

сравнение PHP и Ruby является хорошей иллюстрацией здесь. Оба являются динамически типизированными языками, но PHP имеет много неявных преобразований, а Ruby (возможно, удивительно, если вы с ним незнакомы) - нет.

статический / динамический против сильного / слабого

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

Итак, чтобы ответить на ваш вопрос: еще один способ взглянуть на это, это в основном правильно сказать, что статическая типизация-это безопасность типа времени компиляции, а сильная типизация-безопасность типа времени выполнения.

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

но важно понимать, что язык может быть статическим / сильным, статическим/слабым, динамическим/сильным или динамическим / слабым.


Strongly typed означает, что существуют ограничения между преобразованиями между типами. Статически типизированный означает, что типы не являются динамическими - вы не можете изменить тип переменной после ее создания.


принуждение данных не обязательно означает слабой типизацией, потому что иногда его сахаром syntacical:

приведенный выше пример Java слабо типизирован из-за

String s = "abc" + 123;

не слабо типизированный пример, потому что его действительно делают:

String s = "abc" + new Integer(123).toString()

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

это в отличие от C. C является одним из лучших примеров слабо типизированных. Среда выполнения понятия не имеет, является ли 4 байта целым числом, структурой, указателем или 4 символами.

среда выполнения языка действительно определяет, является ли его слабо типизированным в противном случае его действительно справедливым мнением.

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


оба полюса на двух разных осях:

  • сильно типизированные и слабо типизированные
  • статически типизированный и динамически типизированный

типизированы означает, что a не будет автоматически преобразован из одного типа в другой. Слабо набранная противоположность: Perl может использовать строку типа "123" в числовом контексте, автоматически преобразуя его в int 123. Строго типизированный язык, такой как python, не будет делать этот.

статически типизированный означает, что компилятор вычисляет тип каждой переменной во время компиляции. Динамически типизированные языки определяют только типы переменных во время выполнения.


сильная типизация, вероятно, означает, что переменные имеют четко определенный тип и что существуют строгие правила объединения переменных разных типов в выражениях. Например, если A-целое число, А B-float, то строгое правило о A+B может заключаться в том, что A приводится к float и результат возвращается как float. Если A-целое число, А B-строка, то строгое правило может заключаться в том, что A+B недопустимо.

статическая типизация, вероятно, означает, что типы назначаются при компиляции время (или его эквивалент для некомпилированных языков) и не может изменяться во время выполнения программы.

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

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


одно не подразумевает другое. Чтобы язык был статически typed это означает, что типы всех переменных известны или выводятся во время компиляции.

A сильно типизированный язык не позволяет использовать один тип в другой. C-слабо типизированный язык и является хорошим примером того, что строго типизированные языки не позволяют. В C можно принять элемент данных неправильного типа, и он не будет жаловаться. В строго типизированных языках не может.


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