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

JavaScript с несколькими изменениями:

function deleteRow(btn) {
  var row = btn.parentNode.parentNode;
  row.parentNode.removeChild(row);
}

И HTML с небольшой разницей:

<table id="dsTable">
  <tbody>
    <tr>
      <td>Relationship Type</td>
      <td>Date of Birth</td>
      <td>Gender</td>
    </tr>
    <tr>
      <td>Spouse</td>
      <td>1980-22-03</td>
      <td>female</td>
      <td><input type="button" value="Add" onclick="add()"/></td>
      <td><input type="button" value="Delete" onclick="deleteRow(this)"/></td>
    </tr>
    <tr>
      <td>Child</td>
      <td>2008-23-06</td>
      <td>female</td>
      <td><input type="button" value="Add" onclick="add()"/></td>
      <td><input type="button" value="Delete" onclick="deleteRow(this)"/></td>
    </tr>
  </tbody>
</table>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
392
задан Jamal 11 September 2016 в 19:33
поделиться

7 ответов

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

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

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

Статическое и динамическое

Противоположностью статически типизированному является «динамически типизированное», что означает, что

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

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

Сильный vs слабый

Противоположностью «строго типизированного» является «слабо типизированный», что означает, что вы можете обойти систему типов. C, как известно, слабо типизирован, потому что любой тип указателя может быть преобразован в любой другой тип указателя простым преобразованием. Паскаль должен был быть строго типизированным, но недосмотр в его конструкции (записи непомеченных вариантов) привел к лазейке в системе типов, поэтому технически он плохо типизирован. Примеры действительно строго типизированных языков включают CLU, Standard ML , и Haskell. На самом деле стандартный ML претерпел несколько изменений, чтобы устранить лазейки в системе типов, которые были обнаружены после того, как язык получил широкое распространение.

Что здесь происходит на самом деле?

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

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

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

  • Профессионалы не могут прийти к единому мнению о том, что означают эти термины.

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

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

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

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

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

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

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

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

498
ответ дан 22 November 2019 в 23:32
поделиться

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

12
ответ дан 22 November 2019 в 23:32
поделиться

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

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

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

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

15
ответ дан 22 November 2019 в 23:32
поделиться

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

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

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

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

8
ответ дан 22 November 2019 в 23:32
поделиться

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

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

String s = "abc" + 123;

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

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

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

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

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

РЕДАКТИРОВАТЬ: После дальнейших размышлений это не обязательно верно, поскольку среда выполнения не обязательно должна иметь все типы, переопределенные в системе времени выполнения, чтобы быть системой со строгой типизацией. Haskell и ML имеют такой полный статический анализ, что они могут исключить информацию о типе из среды выполнения.

11
ответ дан 22 November 2019 в 23:32
поделиться

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

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

8
ответ дан 22 November 2019 в 23:32
поделиться

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

Статическая / динамическая типизация

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

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

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

String s = "abcd";

s «навсегда» будет String . В течение своей жизни он может указывать на разные String s (поскольку s является ссылкой в ​​Java). Он может иметь значение null , но никогда не будет ссылаться на Integer или список . Это статическая типизация.

В 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

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

Сильная / Слабая типизация

(Редактировать предупреждение!)

Сильная типизация - это фраза, не имеющая общепринятого значения. Большинство программистов, которые используют этот термин для обозначения чего-то другого, кроме статической типизации, используют его, чтобы подразумевать, что существует дисциплина типов, которая обеспечивается компилятором. Например, в CLU есть строгая система типов, которая не позволяет клиентскому коду создавать значение абстрактного типа, кроме как с помощью конструкторов, предоставляемых этим типом. C имеет довольно сильную систему типов, но ее можно до некоторой степени «подорвать», потому что программа всегда может привести значение одного типа указателя к значению другого типа указателя. Так, например, в C вы можете взять значение, возвращаемое функцией 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 преобразуется в логическое ложное , и, таким образом, условие действительно истинно. Решение состоит в том, чтобы использовать === вместо == , чтобы избежать неявного преобразования.

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

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

val = "abc" + 123

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

val = "abc" + 123.to_s

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

Статическая / динамическая и сильная / слабая

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

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

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

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

236
ответ дан 22 November 2019 в 23:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: