Статический / Динамический против Сильный / Слабый - PullRequest
289 голосов
/ 28 февраля 2010

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

Ответы [ 10 ]

379 голосов
/ 28 февраля 2010
  • Статическая / динамическая печать составляет около при получении информации о типе (либо во время компиляции, либо во время выполнения)

  • Сильная / слабая типизация означает , насколько строго различаются типы (например, пытается ли язык выполнить неявное преобразование из строк в числа).

Более подробную информацию см. На вики-странице .

198 голосов
/ 28 февраля 2010

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

Строгая типизация обычно означает, что в системе типов нет лазеек , тогда как слабая типизация означает, что система типов может быть подорвана (аннулируя любые гарантии) , Термины часто используются неправильно для обозначения статической и динамической типизации. Чтобы увидеть разницу, подумайте о C: язык проверяется на тип во время компиляции (статическая типизация), но существует множество лазеек; вы можете в значительной степени привести значение любого типа к другому типу того же размера - в частности, вы можете свободно приводить типы указателей. Паскаль был языком, который предназначался для строгой типизации, но, как известно, имел непредвиденную лазейку: вариант записи без тега.

Реализации строго типизированных языков часто приобретают лазейки со временем, обычно, так что часть системы времени выполнения может быть реализована на языке высокого уровня. Например, в Objective Caml есть функция с именем Obj.magic, которая во время выполнения просто возвращает свой аргумент, но во время компиляции преобразует значение любого типа в значение любого другого типа. Мой любимый пример - Modula-3, дизайнеры которого назвали свою конструкцию для литья типов LOOPHOLE.

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

64 голосов
/ 30 ноября 2015

Проще говоря, в статически типизированном языке типом является статически , то есть, когда вы устанавливаете переменную для типа, вы НЕ МОЖЕТЕ изменить ее. Это связано с тем, что типизация связана с переменной, а не со значением, к которому она относится.

Например, в Java:

String str = "Hello";  //statically typed as string
str = 5;               //would throw an error since java is statically typed

В то время как в динамически типизированном языке типом является динамический , то есть после того, как вы установите переменную в тип, вы МОЖЕТЕ изменить ее. Это связано с тем, что типизация связана со значением, а не с переменной.

Например, в Python:

str = "Hello" # it is a string
str = 5       # now it is an integer; perfectly OK

С другой стороны, строгая / слабая типизация в языке связана с неявными преобразованиями типов (частично взятыми из ответа @ Dario):

Например, в Python:

str = 5 + "hello" 
# would throw an error since it does not want to cast one type to the other implicitly. 

, тогда как в PHP:

$str = 5 + "hello"; // equals 5 because "hello" is implicitly casted to 0 
// PHP is weakly typed, thus is a very forgiving language.

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

19 голосов
/ 28 февраля 2010

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

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

В строго типизированном языке тип объекта не изменяется - int всегда является int и попытка использовать его в качестве строки приведет к ошибке. И Java, и Python строго типизированы.

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

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

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

13 голосов
/ 31 марта 2014

Сегодня, исследуя эту тему, я наткнулся на эту замечательную статью http://blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html Она многое прояснила для меня, и я подумал, что это может добавить некоторые из замечательных ответов выше.

Сильный и слабый набор текста:

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

Статический и динамический типы

Это почти единственная распространенная классификация систем типов. это имеет реальное значение. На самом деле, это значение часто недооцениваемые [...] системы динамического и статического типа две совершенно разные вещи, чьи цели бывают частично пересекаться.

Статическая система типов - это механизм, с помощью которого компилятор проверяет исходный код и назначает метки (называемые «типы») на куски синтаксис, а затем использует их, чтобы вывести что-то о программе поведение. Система динамических типов - это механизм, с помощью которого компилятор генерирует код для отслеживания вида данных (по совпадению, также называется его "тип") используется программой. Использование одного и того же слова «тип» в каждой из этих двух систем, конечно, не совсем случайна; все же это лучше всего понимать как наличие своего рода слабого историческая значимость. Большая путаница возникает в результате попытки найти мировоззрение, в котором «тип» действительно означает одно и то же в обоих системы. Это не так.

Явные / неявные типы:

Когда эти термины используются, они относятся к степени, в которой Компилятор расскажет о статических типах частей программы. Все Языки программирования имеют некоторую форму рассуждений о типах. Немного иметь больше, чем другие. ML и Haskell имеют неявные типы, в которых нет (или очень мало, в зависимости от языка и используемых расширений) декларации нужны. Java и Ada имеют очень явные типы, и каждый постоянно объявляет типы вещей. Все вышеперечисленное есть (относительно, по сравнению с C и C ++, например) сильный статический тип системы.

6 голосов
/ 07 августа 2018

С Скотта Прагматика языка программирования , 3-е издание стр. 291, у нас есть

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

Несколько примеров: Ада строго типизирована, и по большей части статически типизированный (определенные ограничения типа должны быть проверены при запуске время). Реализация на Паскале также может выполнять большую часть проверки типов во время компиляции, хотя язык не совсем строго типизирован: непомеченные вариантные записи (которые будут обсуждаться в разделе 7.3.4) являются его только лазейка С89 значительно сильнее набран, чем его диалекты предшественника, но все еще значительно менее сильно напечатаны, чем Паскаль. Его лазейки включают союзы, подпрограммы с переменными числами параметров и совместимости указателей и массивов (будет обсуждается в разделе 7.7.1). Реализации C редко проверяют что-нибудь во время выполнения.

Динамическая (во время выполнения) проверка типов является формой позднего связывания и имеет тенденцию можно найти в языках, которые задерживают другие проблемы до времени выполнения, как Что ж. Lisp и Smalltalk типизируются динамически (хотя и строго). Наиболее языки сценариев также динамически типизируются; некоторые (например, Python и Руби) сильно типизированы. Языки с динамическим ограничением обычно динамически типизированный (или не типизированный вообще): если компилятор не может определить объект, к которому относится имя, обычно не может определить Тип объекта либо.

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

Я попытался перевести описание Скотта в хорошую диаграмму, которую я разместил ниже.

The Static/Dynamic - Strong/Weak Typing Plane

5 голосов
/ 28 июля 2011

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

Вот два примера:

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

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

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

3 голосов
/ 19 февраля 2017

Статически v / s динамически типизированные языки

  • Статически типизированные языки - это языки, в которых проверка типов выполняется во время компиляции, поэтому это также означает, что в статически типизированных языках каждая переменная имеет тип и не изменяется в течение курса. Теперь напротив, динамически типизированные языки - это языки, в которых проверка типов выполняется во время выполнения, и проверка типов не выполняется во время компиляции, поэтому это также означает, что в динамически типизированных языках может быть или не быть тип, связанный с переменные , и если тип связан, то это может быть универсальный тип, такой как «var» в JS, который подходит как для строки, так и для числа.
    • «Реализации языков с динамической проверкой типов обычно связывают каждый исполняемый объект с тегом типа (т. Е. Ссылкой на тип), содержащим информацию о его типе. Эта информация о типе среды выполнения (RTTI) также может использоваться для реализации динамической отправки, позднего связывания, приведения вниз, отражения и аналогичных функций ».
  • Даже если язык статически типизирован, все же он может иметь некоторую динамически типизированную функцию, что в основном означает, что некоторая проверка типов также выполняется во время выполнения. Это полезно при приведении типов.
    • «Ряд полезных и распространенных функций языка программирования невозможно проверить статически, например, при понижении частоты. Таким образом, многие языки будут иметь как статическую, так и динамическую проверку типов; средство проверки статического типа проверяет, что оно может, а средство динамической проверки - все остальное. ”
  • «Некоторые языки позволяют писать код, который не является безопасным для типов. Например, в C программисты могут свободно приводить значения между любыми двумя типами, которые имеют одинаковый размер. ”
  • Преимущество «статически» типизированных языков заключается в том, что:
    • Поскольку большая часть проверки типов выполняется во время компиляции, интерпретатор или среда выполнения могут работать на полной скорости, не беспокоясь о типах.
    • Это приводит к уменьшению числа исключений во время выполнения или ошибок, связанных с типом, поскольку большая часть проверки типов выполняется во время компиляции.
  • Преимущество «динамически» типизированных языков заключается в том, что:
    • Они могут помочь в чрезвычайно быстром прототипировании, поскольку разработчику не нужно понимать систему типов, поэтому dev может свободно создавать переменные и запускать их, что приводит к очень быстрому прототипированию.
  • Список статически и динамически типизированных языков :
    • Статический:
      • Java
      • C (C - статически типизированный язык, но менее «строго» типизированный по сравнению с Java, поскольку он допускает более неявные преобразования)
    • C #
  • Динамически:
    • PERL
    • PHP
    • Python
    • JavaScript
    • рубин
Проверка типов является важной функцией безопасности. Предположим, проверка типов не производится, и метод принимает объект типа «BankAccount», у которого есть метод, называемый «creditAccount (BankAccountDetails)», теперь во время выполнения, если нет проверки типов, я могу передать объект моего собственного класса, который имеет тот же метод «creditAccount (BankAccountDetails)», и он будет выполнен, учитывая, что мы говорим об объектно-ориентированном языке, потому что ООП поддерживает «полиморфизм», и здесь мы обсуждаем не что иное, как «полиморфизм». Таким образом, в основном объектно-ориентированный язык (что в основном означает, что он поддерживает «полиморфизм»), который не имеет строгой проверки типов, может привести к проблемам безопасности.

Сильно v / s слабо типизированные языки

  • Строго типизированные языки - это те, на которыхнеявные преобразования не допускаются в случае потери точности. Например, в Java вы можете привести «int к long», потому что нет потери точности, но вы не можете «неявно» привести «long к int», потому что будет потеря точности. Напротив, в слабо типизированных языках допускаются неявные преобразования даже в случае потери точности.
  • Я думаю, что динамически типизированный язык также может быть строго типизированным языком, если «во время выполнения» он не допускает неявных преобразований, в которых наблюдается потеря точности.

Хорошие дальнейшие чтения

1 голос
/ 06 мая 2017

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

Динамически типизированные языки обычно не требуют, чтобы объявления переменных имели типы, и они выводят типы переменных на основе типа, вычисляемого в результате оценки правой части каждого оператора присваивания или фактических параметров вызова функции. Поскольку переменной может быть присвоено несколько назначений в течение срока ее службы, ее тип может меняться со временем, и именно поэтому она называется «динамически типизированной». Кроме того, среда выполнения должна отслеживать текущий тип для каждой переменной, поэтому тип связан со значением, а не с объявлением переменной. Это можно считать системой информации о типах среды выполнения (RTTI).

Элементы статически и динамически типизированных языков могут быть объединены. Например, C # поддерживает как статически, так и динамически типизированные переменные, а объектно-ориентированные языки обычно поддерживают понижающую иерархию типов. Языки со статической типизацией обычно предоставляют различные способы обойти проверку типов, например, используя приведение, отражение и динамический вызов.

Сильная и слабая типизация - это континуум того, насколько язык пытается предотвратить ошибки из-за использования переменной, как если бы это был один тип, тогда как на самом деле это другой тип. Например, и C, и Java являются статически типизированными языками, однако в Java используется гораздо более строгая проверка типов, чем в C. Следующий код на C с радостью компилируется и выполняется и помещает случайное значение в переменную b во время выполнения, скорее всего, вызывая ошибка:

char *a = "123";
int b = (int)a;

Эквивалентный код Java вызовет ошибку компиляции, что обычно предпочтительнее:

String a = "123"
int b = (int)a;
0 голосов
/ 08 марта 2019

Я недавно написал статью, объясняющую эту точную тему:

https://dev.to/jiangh/type-systems-dynamic-versus-static-strong-versus-weak-b6c

...