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

Я много слышал, что новые языки программирования динамически типизированы, но что это на самом деле означает, когда мы говорим, что язык динамически типизирован против статически типизирован?

16 ответов


статически типизированные языки

язык со статической типизацией, если тип переменной известен во время компиляции. Для некоторых языков это означает, что вы, как программист, должны указать, какой тип каждой переменной (например: Java, C, C++); другие языки предлагают некоторую форму определение типа, возможность системы типов вывести тип переменной (например: OCaml, Haskell, Scala, Kotlin)

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

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

язык динамически типизируется, если тип связан со значениями времени выполнения, а не с именованными переменными / полями / etc. Это означает, что вы, как программист, можете писать немного быстрее, потому что вам не нужно каждый раз указывать типы (если только вы не используете статически типизированный язык с определение типа). Пример: Perl, Ruby, Питон

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

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


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

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


вот пример, контрастирующий с тем, как Python (динамически типизированный) и Go (статически типизированный) обрабатывают ошибку типа:

def silly(a):
    if a > 0:
        print 'Hi'
    else:
        print 5 + '3'

делает проверку типа во время выполнения, и поэтому:

silly(2)

работает отлично, и производит ожидаемый результат Hi. Ошибка возникает только при попадании в проблемную строку:

silly(-1)

производит

TypeError: unsupported operand type(s) for +: 'int' and 'str'

потому что соответствующая строка была фактически выполнена.

Go с другой стороны, проверка типов во время компиляции:

package main

import ("fmt"
)

func silly(a int) {
    if (a > 0) {
        fmt.Println("Hi")
    } else {
        fmt.Println("3" + 5)
    }
}

func main() {
    silly(2)
}

выше не будет компилироваться, со следующей ошибкой:

invalid operation: "3" + 5 (mismatched types string and int)

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

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

String str = "Hello";  //variable str statically typed as string
str = 5;               //would throw an error since str is supposed to be a string only

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

например в Python:

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

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

подводя итог, тип описывает (или описал) переменные в языке, а не сам язык. Это могло быть лучше использовать как язык со статически типизированными переменными и язык с динамически типизированными переменными ИМХО.

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

динамически типизированные языки обычно интерпретируются, поэтому проверка типа (если таковая имеется) происходит во время выполнения, когда они используются. Это, конечно, приносит некоторую стоимость производительности и является одной из причин того, что динамические языки (например, python, ruby, php) не масштабируются так хорошо, как типизированные (java, c# и т. д.). С другой стороны, статически типизированные языки имеют большую стоимость запуска: обычно вы пишете больше кода, более сложный код. Но это окупится позже.

хорошо, что обе стороны заимствуют функции с другой стороны. Типизированные языки включают в себя более динамические функции, например, дженерики и динамические библиотеки на c# и динамические языки включают в себя больше проверки типов, например, аннотации типа в python или взломать вариант PHP, которые обычно не являются ядром языка и могут использоваться по требованию.

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


http://en.wikipedia.org/wiki/Type_system

статическая типизация

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

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

if <complex test> then 42 else <type error>

будет отклонен как неправильно набранный, потому что статический анализ не может определить что другой ветви не будет взятый.[1] консервативное поведение статического типа шашки выгодно, когда оценивает значение false нечасто: A статический тип контролер может обнаружить тип ошибки в редко используемых путях кода. Без статического типа проверяя, даже тесты, покрытие кода со 100% код покрытие может быть не в состоянии найти такие ошибки типа. Тесты покрытия кода могут не обнаружить такие ошибки типа потому что сочетание всех мест где создаются значения и все места, где используется определенное значение необходимо принимать во внимание.

наиболее широко используемый статически типизированный языки формально не безопасны для типов. У них есть "лазейки" в спецификация языка программирования позволяет программистам писать код что обходит проверку выполняется статическая проверка типа и поэтому решайте более широкий круг проблем. Например, Java и большинство C-style языки имеют тип punning, и Haskell имеет такие функции, как unsafePerformIO: такие операции могут быть небезопасными во время выполнения, в том, что они могут причина нежелательного поведения Из-за неправильный ввод значений при запуск программы.

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

язык программирования называется динамически типизированный или просто "динамический", когда большинство своего типа проверяя выполняется во время выполнения, в отличие от во время компиляции. В динамической типизации, типы связаны со значениями not переменная. Динамически типизированные языки включают в Groovy, JavaScript и сюсюкать, Луа, Цель-C, Perl (в отношении пользовательские типы, но не встроенные типы), PHP, Пролог, Python, Ruby, Smalltalk и Tcl. По сравнению со статическими типизация, динамическая типизация может быть больше гибкий (например путем позволять программы создать типы и возможности по данным времени выполнения), хотя на за счет меньшего количества априорных гарантий. Это потому, что динамически типизированный язык принимает и пытается выполните некоторые программы, которые могут быть управляется как недопустимый статическим типом контролер.

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

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

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

ссылки

  1. Pierce, Benjamin (2002). Типы и языки программирования. МИТ пресс. ISBN 0-262-16209-1.

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

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

однако, если бы мы увеличили нетипизированное лямбда-исчисление примитивными числами и арифметическими операциями, мы могли бы выполнять бессмысленные операции, такие как добавление двух лямбда-членов вместе:(λx.x) + (λy.y). Можно утверждать, что единственное разумное, что нужно сделать, это сигнализировать об ошибке, когда это происходит, но чтобы это сделать, каждое значение должно быть помечено индикатором, который указывает является ли термин лямбда-термином или числом. Затем оператор сложения проверяет, действительно ли оба аргумента помечены как числа, а если нет, сигнализирует об ошибке. Обратите внимание, что эти теги не типы, потому что типы являются свойствами программ, а не значений, производимых этими программами.

uni-типизированный язык, который делает это, называется динамически типизированным.

такие языки, как JavaScript, Python и Ruby, являются однотипными. Опять же,typeof оператор в JavaScript и type функция в Python имеет вводящие в заблуждение имена; они возвращают теги, связанные с операндами, а не их типы. Аналогично,dynamic_cast В C++ и instanceof в Java do не выполнить проверку типа.


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

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


сладкие и простые определения, но соответствующие потребности: Статически типизированные языки связывают тип с переменной для всей области (Seg: SCALA) Динамически типизированные языки связывают тип с фактическим значением, на которое ссылается переменная.


Compiled vs. Interpreted

"при переводе исходного кода"

  • Исходный Код: оригинальный код (обычно набирается человеком в компьютер)
  • перевод: преобразование исходного кода в то, что компьютер может читать (т. е. машинный код)
  • Времени: период, когда программа выполняет команды (после компиляции, если скомпилирована)
  • составлен Язык: код переведен до выполнения
  • Интерпретируемый Язык: код "на лету", во время исполнения

введя

"при проверке типов"

5 + '3' - Это пример ошибки типа типизированы языки, такие как Go и Python, потому что они не допускают "принуждения типа" - > возможность для значения изменять тип в определенных контекстах, таких как слияние двух типы. слабо типизированные языки, такие как JavaScript, не будут выдавать ошибку типа (результаты в '53').

  • статический: типы, проверенные перед выполнением
  • динамический: типы проверяются на лету, во время выполнения

определения "Static & Compiled" и "Dynamic & Interpreted" довольно похожи...но помните, что это "когда проверяются" против ", когда исходный код переводится".

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


Пример Python

Динамический, Интерпретируемый

def silly(a):
    if a > 0:
        print 'Hi'
    else:
        print 5 + '3'

silly(2)

поскольку Python интерпретируется и динамически типизируется, он только переводит и проверяет тип кода, на котором он выполняется. The else блок никогда не выполняется, поэтому 5 + '3' никогда даже не смотрел Ат!

что, если он был статически типизированный?

ошибка типа будет выдана еще до запуска кода. Он по-прежнему выполняет проверку типа Перед выполнением, даже если он интерпретируется.

что, если он был составлен?

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


Перейти

Статический, Составленном

package main

import ("fmt"
)

func silly(a int) {
  if (a > 0) {
      fmt.Println("Hi")
  } else {
      fmt.Println("3" + 5)
  }
}

func main() {
  silly(2)
}

типы проверяются перед запуском (статические) и ошибка типа сразу поймали! Типы все равно будут проверены до выполнения, если он был интерпретирован, имея тот же результат. Если бы он был динамическим, он не вызывал бы ошибок, даже если бы код просматривался во время компиляции.


производительность

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

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

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

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


Больше Различий

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

num = 2
num = '3' // ERROR

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


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

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

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

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

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

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

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

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


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

(int a; a может принимать только целочисленные значения типа во время выполнения)

Например: C, C++, Java

динамически типизированные языки: varialbes может получать разные значения во время выполнения, и тип определяется во время выполнения.

(var a; a может принимать любые значения во время выполнения)

Например: Ruby, Питон.


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

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


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


на статически типизированный язык, каждое имя переменной связано как 1.к типу (во время компиляции, посредством объявления данных) 2.к объекту. Привязка к объекту необязательна - если имя не привязано к объекту, имя называется null. В динамически типизированный язык, каждое имя переменной (если оно не равно null) привязано только к объекту.

имена привязаны к объектам во время выполнения с помощью оператора присваивания, и это можно привязать имя к объектам разных типов во время выполнения программы.


Статическая Типизация: Такие языки, как Java и Scala, являются статическими.

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

для ex. int x; x = 10;