Означает ли статическая типизация, что вам нужно привести переменную, если вы хотите изменить ее тип?

Существуют ли какие-либо другие способы изменения типа переменной в статически типизированном языке, таком как Java и C++, кроме «приведения»?

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


person Community    schedule 01.03.2009    source источник
comment
Приведение типов не изменяет тип переменной. Результатом приведения является новое выражение, которое неявно нигде не хранится.   -  person recursive    schedule 01.03.2009


Ответы (7)


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

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

Эти две противоположности можно свободно комбинировать:

  • Java статически и строго типизирована
  • C статически и слабо типизирован (арифметика указателей!)
  • Ruby динамически и строго типизирован
  • JavaScript динамически и слабо типизирован

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

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

person Michael Borgwardt    schedule 01.03.2009

В C++/Java вы не можете изменить тип переменной.

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

Динамическая типизация. Тип переменной может меняться во время выполнения, например. в JavaScript:

js> x="5" <-- String
5
js> x=x*5 <-- Int
25
person Johannes Weiss    schedule 01.03.2009
comment
Разве приведение не меняет тип? - person ; 01.03.2009
comment
@Mark, вы можете изменить тип ЗНАЧЕНИЯ, но не ПЕРЕМЕННОЙ. интервал я = 42; // я не могу измениться на число с плавающей запятой. Однако значение i (42) может. Смотрите мой пример. - person strager; 01.03.2009
comment
Не тип переменной. Он может изменить тип значения/выражения - person Johannes Weiss; 01.03.2009
comment
Тип объекта во время выполнения всегда будет одним и тем же. Тип ссылки может быть операцией объекта среды выполнения или чем-то еще в иерархии. - person John Ellinwood; 01.03.2009

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

person tvanfosson    schedule 01.03.2009

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

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

person Fabian Steeg    schedule 01.03.2009

Вам не нужно явное приведение типов. Во многих случаях работает неявное приведение.

Например:

int i = 42;
float f = i; // f ~= 42.0
int b = f;   // i == 42

class Base {
};

class Subclass : public Base {
};

Subclass *subclass = new Subclass();
Base *base = subclass;  // Legal

Subclass *s = dynamic_cast<Subclass *>(base); // == subclass.  Performs type checking.  If base isn't a Subclass, NULL is returned instead.  (This is type-safe explicit casting.)

Однако вы не можете изменить тип переменной. Однако вы можете использовать объединения в C++ для достижения динамической типизации.

person strager    schedule 01.03.2009

Давайте посмотрим на Java как на язык со статической типизацией и на JavaScript как на динамический. В Java для объектов переменная является ссылкой на объект. Объект имеет тип времени выполнения, а ссылка имеет тип. Тип ссылки должен быть типом объекта среды выполнения или одного из его предков. Так работает полиморфизм. Вы должны выполнить приведение, чтобы подняться по иерархии ссылочного типа, но не вниз. Компилятор обеспечивает выполнение этих условий. В таком языке, как JavaScript, ваша переменная — это просто переменная. Вы можете сделать так, чтобы он указывал на любой объект, который вы хотите, и вы не знаете его тип, пока не проверите.

Однако для преобразований существует множество методов, таких как toInteger и toFloat в Java, которые выполняют преобразование и создают объект нового типа с тем же относительным значением. В JavaScript тоже есть методы преобразования, но они тоже генерируют новые объекты.

person John Ellinwood    schedule 01.03.2009
comment
Итак, toFloat в Java не изменяет существующий объект. Я смотрю на Ruby, где вы можете сказать x = abc, а затем x = 100 - вы сказали, что Javascript генерирует новые объекты, но я думал, что Ruby просто изменяет существующий объект на новый тип. Или я ошибаюсь? - person ; 01.03.2009

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

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

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

Dim id
id = Request.QueryString("id") ' this variable is now a string
If id = "42" Then
  id = 142 ' sometimes turned into a number
End If
If id > 100 Then ' will not work properly for strings

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

lngId = Request.QueryString("id") ' putting a string in a numeric variable

strId = 42 ' putting a number in a string variable
person Guffa    schedule 01.03.2009