Кроме того, одно подразумевает другое?
В чем разница между языком со строгой типизацией и языком со статической типизацией?
Ответы (8)
В чем разница между языком со строгой типизацией и языком со статической типизацией?
Статически типизированный язык имеет систему типов, которая проверяется во время компиляции реализацией (компилятором или интерпретатором). Проверка типа отклоняет некоторые программы, а программы, прошедшие проверку, обычно поставляются с некоторыми гарантиями; например, компилятор гарантирует не использовать целочисленные арифметические инструкции для чисел с плавающей запятой.
Нет реального согласия относительно того, что означает «строго типизированный», хотя наиболее широко используемое определение в профессиональной литературе состоит в том, что в «строго типизированном» языке программист не может обойти ограничения, налагаемые системой типов. . Этот термин почти всегда используется для описания языков со статической типизацией.
Статический против динамического
Противоположностью статической типизации является "динамическая типизация", что означает, что
- Значения, используемые во время выполнения, классифицируются по типам.
- Существуют ограничения на использование таких значений.
- Когда эти ограничения нарушаются, нарушение регистрируется как ошибка (динамического) типа.
Например, Lua, язык с динамической типизацией, среди прочего имеет строковый, числовой и логический тип. . В Lua каждое значение принадлежит ровно одному типу, но это не является требованием для всех динамически типизированных языков. В Lua допустимо объединять две строки, но нельзя объединять строку и логическое значение.
Сильный против слабого
Противоположностью «строго типизированного» является «слабо типизированный», что означает, что вы можете обойти систему типов. C, как известно, слабо типизирован, потому что любой тип указателя может быть преобразован в любой другой тип указателя простым преобразованием. Паскаль должен был быть строго типизированным, но из-за недосмотра в конструкции (записи непомеченных вариантов) в систему типов была образована лазейка, поэтому технически он не является типизированным. Примеры действительно строго типизированных языков включают CLU, Standard ML и Haskell. Фактически, стандартный ML претерпел несколько изменений, чтобы устранить лазейки в системе типов, которые были обнаружены после того, как язык получил широкое распространение.
Что здесь на самом деле происходит?
В целом, говорить о «сильных» и «слабых» оказывается не очень полезно. Наличие лазейки в системе типов менее важно, чем точное количество и характер лазеек, насколько вероятно, что они появятся на практике и каковы последствия использования лазейки. На практике лучше вообще избегать терминов "сильный" и "слабый", потому что
Любители часто объединяют их со «статикой» и «динамикой».
Очевидно, «слабая типизация» используется некоторыми людьми, чтобы говорить об относительной распространенности или отсутствии неявных преобразований.
Профессионалы не могут прийти к единому мнению о том, что означают эти термины.
В целом вы вряд ли проинформируете или просветите свою аудиторию.
Печальная правда заключается в том, что когда дело доходит до систем типов, «сильные» и «слабые» не имеют универсально согласованного технического значения. Если вы хотите обсудить относительную силу систем типов, это Лучше обсудить, какие именно гарантии есть, а какие нет. Например, уместно задать следующий вопрос: «Гарантировано ли, что каждое значение данного типа (или класса) было создано путем вызова одного из конструкторов этого типа?» В C ответ - нет. В CLU, F # и Haskell - да. Что касается C ++, я не уверен, что хотел бы знать.
Напротив, статическая типизация означает, что программы проверяются перед выполнением, и программа может быть отклонена до ее запуска. Динамическая типизация означает, что типы значений проверяются во время выполнения, и плохо типизированная операция может вызвать остановку программы или иным образом сигнализировать об ошибке. во время выполнения. Основная причина статической типизации - исключить программы, которые могут иметь такие «ошибки динамического типа».
Одно подразумевает другое?
На педантичном уровне - нет, потому что слово «сильный» на самом деле ничего не значит. Но на практике люди почти всегда делают одно из двух:
Они (неправильно) используют «сильный» и «слабый» для обозначения «статический» и «динамический», и в этом случае они (неправильно) используют «строго типизированный» и «статически типизированный» как синонимы.
Они используют «сильные» и «слабые» для сравнения свойств систем статического типа. Очень редко можно услышать, как кто-то говорит о «сильной» или «слабой» системе динамического типа. За исключением FORTH, у которого на самом деле нет никакой системы типов, я не могу придумать язык с динамической типизацией, где можно было бы разрушить систему типов. По определению, эти проверки встроены в механизм выполнения, и каждая операция перед выполнением проверяется на работоспособность.
В любом случае, если человек называет язык «строго типизированным», он, скорее всего, будет говорить о языке со статической типизацией.
IStream
, вы знаете, что он реализует этот интерфейс - вы не получите нарушения типа при вызове IStream.Read
, даже если вы не знаете во время компиляции, является ли фактический тип FileStream
или HttpStream
или что-то еще.
- person Luaan; 30.11.2016
Это часто понимают неправильно, поэтому позвольте мне прояснить это.
Статический / динамический набор текста
Статическая типизация - это когда тип привязан к переменной. Типы проверяются во время компиляции.
Динамический тип - это когда тип привязан к значению. Типы проверяются во время выполнения.
Так, например, в Java:
String s = "abcd";
s
будет "навсегда" String
. В течение своей жизни он может указывать на разные String
(поскольку s
является ссылкой в Java). Он может иметь значение null
, но никогда не будет относиться к Integer
или List
. Это статическая типизация.
В PHP:
$s = "abcd"; // $s is a string
$s = 123; // $s is now an integer
$s = array(1, 2, 3); // $s is now an array
$s = new DOMDocument; // $s is an instance of the DOMDocument class
Это динамическая типизация.
Сильный / Слабый набор текста
(Изменить оповещение!)
Строгое печатание - это фраза, не имеющая общепринятого значения. Большинство программистов, которые используют этот термин для обозначения чего-то другого, кроме статической типизации, используют его, чтобы подразумевать, что существует дисциплина типов, которая обеспечивается компилятором. Например, в CLU есть строгая система типов, которая не позволяет клиентскому коду создавать значение абстрактного типа, кроме как с помощью конструкторов, предоставляемых этим типом. C имеет довольно строгую систему типов, но ее можно до некоторой степени «подорвать», потому что программа всегда может привести значение одного типа указателя к значению другого типа указателя. Так, например, в C вы можете взять значение, возвращаемое malloc()
, и весело преобразовать его в FILE*
, и компилятор не будет пытаться остановить вас или даже предупредить вас о том, что вы делаете что-то коварное.
(В исходном ответе что-то говорилось о значении «не меняющий тип во время выполнения». Я знал многих разработчиков языков и авторов компиляторов и не знал ни одного, который бы говорил о значениях, меняющих тип во время выполнения, за исключением, возможно, некоторых очень продвинутых исследований в типе системы, где это известно как "сильная проблема обновления".)
Слабая типизация означает, что компилятор не обеспечивает соблюдение требований к типу или, возможно, это применение можно легко отменить.
В оригинале этого ответа слабая типизация объединилась с неявным преобразованием (иногда также называемым «неявным продвижением»). Например, в Java:
String s = "abc" + 123; // "abc123";
Этот код является примером неявного продвижения: 123 неявно преобразуется в строку перед объединением с "abc"
. Можно утверждать, что компилятор Java переписывает этот код как:
String s = "abc" + new Integer(123).toString();
Рассмотрим классическую проблему PHP "начинается с":
if (strpos('abcdef', 'abc') == false) {
// not found
}
Ошибка здесь в том, что strpos()
возвращает индекс соответствия, равный 0. 0 переводится в логическое значение false
, и, таким образом, условие действительно истинно. Решение состоит в том, чтобы использовать ===
вместо ==
, чтобы избежать неявного преобразования.
Этот пример показывает, как сочетание неявного преобразования и динамической типизации может сбить программистов с пути.
Сравните это с Ruby:
val = "abc" + 123
что является ошибкой времени выполнения, потому что в Ruby объект 123 не неявно конвертируется только потому, что он передается методу +
. В Ruby программист должен сделать преобразование явным:
val = "abc" + 123.to_s
Хорошая иллюстрация здесь - сравнение PHP и Ruby. Оба являются динамически типизированными языками, но PHP имеет множество неявных преобразований, а Ruby (что, возможно, удивительно, если вы с ним не знакомы) - нет.
Статический / динамический против сильного / слабого
Дело в том, что статическая / динамическая ось не зависит от сильной / слабой оси. Люди путают их, вероятно, отчасти потому, что сильная и слабая типизация не только менее четко определены, но и нет реального консенсуса относительно того, что именно подразумевается под сильным и слабым. По этой причине сильный / слабый набор текста - это скорее оттенок серого, чем черный или белый.
Итак, чтобы ответить на ваш вопрос: другой способ взглянуть на это, который в основном верен, - это сказать, что статическая типизация - это безопасность типа во время компиляции, а строгая типизация - это безопасность типа во время выполнения.
Причина этого в том, что переменные в статически типизированном языке имеют тип, который должен быть объявлен и может быть проверен во время компиляции. Строго типизированный язык имеет значения, которые имеют тип во время выполнения, и программисту трудно подорвать систему типов без динамической проверки.
Но важно понимать, что язык может быть статическим / сильным, статическим / слабым, динамическим / сильным или динамическим / слабым.
"abc" + 123
- это ошибка времени выполнения, а не ошибка компиляции в ruby. Если бы это была ошибка компиляции, рубин был бы статически типизирован.
- person sepp2k; 22.04.2010
Оба являются полюсами на двух разных осях:
- строго типизированный или слабо типизированный
- статически типизированный или динамически типизированный
Строго типизированный означает, что объект не будет автоматически преобразован из одного типа в другой. Слабая типизация - это наоборот: Perl может использовать строку типа "123"
в числовом контексте, автоматически преобразовывая ее в int 123
. Строго типизированный язык, такой как python, этого не сделает.
Статически типизированный означает, что компилятор определяет тип каждой переменной во время компиляции. Языки с динамической типизацией определяют типы переменных только во время выполнения.
Строго типизированный означает, что существуют ограничения между преобразованиями между типами.
Статически типизированный означает, что типы не являются динамическими - вы не можете изменить тип переменной после ее создания.
Принуждение данных не обязательно означает слабую типизацию, потому что иногда это синтаксический сахар:
В приведенном выше примере Java слабо типизирована из-за
String s = "abc" + 123;
Это не слабо типизированный пример, потому что он действительно делает:
String s = "abc" + new Integer(123).toString()
Приведение данных также не является слабо типизированным, если вы создаете новый объект. Java - очень плохой пример слабо типизированного (и любой язык с хорошим отражением, скорее всего, не будет слабо типизированным). Поскольку среда выполнения языка всегда знает, что это за тип (исключением могут быть собственные типы).
В этом отличие от C. C - один из лучших примеров слабо типизированных. Среда выполнения не знает, являются ли 4 байта целым числом, структурой, указателем или 4 символами.
Время выполнения языка действительно определяет, является ли он слабо типизированным, в противном случае это действительно справедливое мнение.
РЕДАКТИРОВАТЬ: После дальнейших размышлений это не обязательно верно, поскольку среда выполнения не должна иметь все типы, повторно введенные в систему времени выполнения, чтобы быть системой со строгой типизацией. Haskell и ML обладают настолько полным статическим анализом, что могут исключить информацию о типе из среды выполнения.
Ответ уже дан выше. Пытаемся провести различие между концепцией «сильная и недельная» и «статическая и динамическая».
Что такое сильно типизированный VS слабо типизированный?
Сильно типизированный: не будет автоматически преобразован из одного типа в другой
В Go или Python, как и в языках со строгой типизацией, "2" + 8 вызовут ошибку типа, потому что они не допускают "приведения типов".
Слабо (слабо) типизированный: будет автоматически преобразован из одного типа в другой. Слабо типизированные языки, такие как JavaScript или Perl, не выдадут ошибку, и в этом случае JavaScript выдаст «28», а perl - 10.
Пример Perl:
my $a = "2" + 8;
print $a,"\n";
Сохраните его в main.pl и запустите perl main.pl
, и вы получите результат 10.
Что такое статический или динамический тип?
В программировании программист определяет статическую типизацию и динамическую типизацию по отношению к точке, в которой проверяются типы переменных. Языки со статической типизацией - это языки, в которых проверка типов выполняется во время компиляции, а языки с динамической типизацией - это языки, в которых проверка типов выполняется во время выполнения.
- Статический: типы проверяются перед запуском
- Динамический: типы проверяются на лету, во время выполнения
Что это значит?
В Go он проверяет набранный перед запуском (статическая проверка). Это означает, что он не только переводит и проверяет тип кода, который он выполняет, но он будет сканировать весь код, и ошибка типа будет выдана еще до того, как код будет запущен. Например,
package main
import "fmt"
func foo(a int) {
if (a > 0) {
fmt.Println("I am feeling lucky (maybe).")
} else {
fmt.Println("2" + 8)
}
}
func main() {
foo(2)
}
Сохраните этот файл в main.go и запустите его, вы получите сообщение об ошибке компиляции.
go run main.go
# command-line-arguments
./main.go:9:25: cannot convert "2" (type untyped string) to type int
./main.go:9:25: invalid operation: "2" + 8 (mismatched types string and int)
Но этот случай не подходит для Python. Например, следующий блок кода будет выполняться для первого вызова foo (2) и завершится ошибкой для второго вызова foo (0). Это потому, что Python динамически типизирован, он только переводит и проверяет типы кода, в котором он выполняется. Блок else никогда не выполняется для foo (2), поэтому "2" + 8 даже не просматривается, а для вызова foo (0) он попытается выполнить этот блок и потерпит неудачу.
def foo(a):
if a > 0:
print 'I am feeling lucky.'
else:
print "2" + 8
foo(2)
foo(0)
Вы увидите следующий вывод
python main.py
I am feeling lucky.
Traceback (most recent call last):
File "pyth.py", line 7, in <module>
foo(0)
File "pyth.py", line 5, in foo
print "2" + 8
TypeError: cannot concatenate 'str' and 'int' objects
Одно не подразумевает другого. Для языка, который будет статически типизирован, это означает, что типы всех переменных известны или предполагаются во время компиляции.
Строго типизированный язык не позволяет использовать один тип как другой. C - это слабо типизированный язык, и он является хорошим примером того, что строго типизированные языки не допускают. В C вы можете передать элемент данных неправильного типа, и он не будет жаловаться. На строго типизированных языках это невозможно.
Сильная типизация, вероятно, означает, что переменные имеют четко определенный тип и что существуют строгие правила комбинирования переменных разных типов в выражениях. Например, если A - целое число, а B - число с плавающей запятой, то строгим правилом для A + B может быть то, что A приводится к типу с плавающей запятой, а результат возвращается как float. Если A - целое число, а B - строка, то строгим правилом может быть недопустимость A + B.
Статическая типизация, вероятно, означает, что типы присваиваются во время компиляции (или ее эквивалента для нескомпилированных языков) и не могут изменяться во время выполнения программы.
Обратите внимание, что эти классификации не исключают друг друга, и я бы ожидал, что они будут часто встречаться вместе. Многие строго типизированные языки также имеют статическую типизацию.
И обратите внимание, что когда я использую слово «вероятно», это потому, что нет общепринятых определений этих терминов. Как вы уже видели из ответов.