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

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

Ответ 1

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

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

Подробнее см. wiki-страницу.

Ответ 2

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

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

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

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

Ответ 3

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

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

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

Ответ 4

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

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

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

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

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

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

Ответ 5

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

Сильная и слабая печать:

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

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

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

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

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

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

Ответ 6

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

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

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

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

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

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

The Static/Dynamic - Strong/Weak Typing Plane

Ответ 7

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

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

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

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

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

Ответ 8

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

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

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

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

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

Ответ 9

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

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

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

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

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

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

String a = "123"
int b = (int)a;