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

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

Ответ 1

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

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

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

Примеры: C, C++, Java, Rust, Go, Scala

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

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

Примеры: Perl, Ruby, Python, PHP, JavaScript

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

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

Ответ 2

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

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

Ответ 3

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

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

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

silly(2)

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

silly(-1)

Выдает

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

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

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

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)

Ответ 4

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

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

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

Подводя итог, тип описывает (или должен был описать) переменные на языке, а не сам язык. Его можно было бы лучше использовать в качестве языка со статически типизированными переменными и языка с динамически типизированными переменными. IMHO.

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

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

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

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

Ответ 5

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

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

Говорят, что язык программирования статическая типизация при проверке типа выполняются во время компиляции как против времени выполнения. При статической типизации, типы связаны с переменными а не значения. Статически типизированные языки включают Ada, C, С++, С#, JADE, Java, Фортран, Хаскелл, М.Л., Паскаль, Перл (в отношении отличия скаляры, массивы, хэши и подпрограммы) и Scala. Статическая типизация является ограниченной формой программы проверка (см. тип безопасности): соответственно, он позволяет много типов ошибки, которые должны быть цикл разработки. Статический тип шашки оценивают только тип информацию, которая может быть определена на время компиляции, но можно проверить что проверяемые условия выполняются для все возможные исполнения программы, которая устраняет необходимость повторять проверки типов каждый раз, когда программа выполнена. Выполнение программы также могут быть более эффективными (т.е. быстрее или снижая память) исключая проверки типа времени выполнения и позволяя другие оптимизации.

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

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

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

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

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

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

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

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

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

Ссылки

  • Пирс, Бенджамин (2002). Типы и языки программирования. MIT Press. ISBN 0-262-16209-1.

Ответ 6

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

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

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

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

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

Ответ 7

Скомпилированный и интерпретированный

"Когда исходный код переводится"

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

Typing

"Когда типы проверяются"

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

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

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

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


Пример Python

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

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

silly(2)

Поскольку Python интерпретируется и динамически типизируется, он только переводит и выполняет код проверки типа, в котором он выполняется. Блок 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)
}

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


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

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

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

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

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


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

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

num = 2
num = '3' // ERROR

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

Ответ 8

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

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

Примеры: C, C++, Java

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

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

Примеры: Ruby, Python.

Ответ 9

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

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

Ответ 10

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

Ответ 11

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

Ответ 12

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

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

Ответ 13

Сильная типизация, вероятно, означает, что переменные имеют четко определенный тип и что существуют строгие правила о объединении переменных разных типов в выражениях. Например, если 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.

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

Ответ 14

Статически Типизированный

Типы проверяются перед выполнением, поэтому ошибки могут быть обнаружены раньше.

Примеры = c++

Динамически Типизированный

Типы проверяются во время выполнения.

Примеры = Питон

Ответ 15

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

Ответ 17

Языки со статической типизацией (компилятор разрешает вызовы методов и компилирует ссылки):

  • обычно лучшая производительность
  • более быстрая обратная связь при ошибках компиляции
  • лучшая поддержка IDE
  • не подходит для работы с неопределенными форматами данных
  • труднее начать разработку, когда модель не определена, когда
  • более длительное время компиляции
  • во многих случаях требуется написать больше кода

Динамически типизированные языки (решения, принимаемые в запущенной программе):

  • низкая производительность
  • более быстрое развитие
  • некоторые ошибки могут быть обнаружены только позже во время выполнения
  • подходит для неопределенных форматов данных (метапрограммирование)

Ответ 18

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

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

Ответ 19

Статический ввод: Языки, такие как Java и Scala, являются статическими.

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

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

System.out.println(х);

Динамический ввод:  Perl - это динамически типизированный язык.

Переменные не обязательно должны быть инициализированы до их использования в коде.

у = 10; используйте эту переменную в более поздней части кода