Вопрос

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

Это было полезно?

Решение

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

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

Смотрите на вики-страница для получения более подробной информации.

Другие советы

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

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

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

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

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

Например, в 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.

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

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

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

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

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

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

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

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

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

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

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

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

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

Явные / Неявные Типы:

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

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

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

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

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

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

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

The Static/Dynamic - Strong/Weak Typing Plane

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

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

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

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

Оба утверждения подчеркивают не противоположные крайности системы типов, а совершенно разные аспекты.Итак , я присоединяюсь к мистеруМнение Рэмси не использовать термины "сильный" и "слабый" для проведения различия между системами типов.

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

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

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

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

Хорошие дальнейшие показания

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

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

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

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

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

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

String a = "123"
int b = (int)a;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top