Типы в языках программирования

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

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

Если вы уже знакомы с каким-нибудь языком программирования, то наверняка в нем вам встречался такой тип как “целое число”, чаще всего его называют int. Как правило, значения этого типа можно складывать, вычитать и умножать. В зависимости от языка программирования, могут быть допустимы и другие операции. Но есть и такие операции, которые нельзя выполнять над целыми числами, например, деление: если разделить 5 на 3, мы не получим целое число, точно так же нельзя применять к ним операцию извлечения корня.

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

То, как язык работает с типами данных и какие возможности предоставляет (или не предоставляет) определяет система типов.

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

Существуют языки программирования, у которых система типов очень мощная. В ней, программу, по сути, можно воспринимать как некоторое математическое утверждение, которое выражено через типы, а компиляцию – как процесс доказательства этого утверждения. И если программа скомпилировалась, то, значит, утверждение доказано. К таким языкам можно отнести Haskell.

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

В зависимости от принятой системы типов языки программирования делят на следующие группы:

  • со статической и динамической типизацией;
  • с сильной и слабой типизацией;
  • с явной и неявной типизацией.

Такая классификация не является исчерпывающей, но она дает некоторое представление о возможностях языков с точки зрения типов.

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

Примеры языков со статической типизацией: C#, Java, C, C++.

Пример кода объявления переменной:

double value = 0.123;

Обратите внимание, что перед именем переменной стоит ее тип – double. Есть языки, в которых тип можно явно не указывать, но при этом, они все равно остаются языками со статической типизацией, в них тип выводится на этапе компиляции, C# поддерживает такой подход:

var value = 0.123;

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

Примеры языков с динамической типизацией: Python, PHP. Пример кода на Python:

value = 0.123

В таких языках используется подход, который называется “утиная типизация” (duck typing). Формула такая: “если крякает как утка, значит, это утка”, если её применить к переменной, то это может звучать как “если переменная связана со значением, которое ведет себя как целое число, значит, тип переменной – это “целое число” (int)”.

Рассмотрим пример:

a = 123
a = "hello"

Эти две строчки являются валидными (правильными, приемлемыми) для языка Python. Происходит следующее: после выполнения первой строки, в памяти создается некоторая область, в которой будет храниться число 123, эта область имеет определенный адрес и с ней связана переменная a. Во второй строке будет создана другая область памяти со своим адресом для хранения строки “hello”, при этом метка a будет отвязана от первой и привязана ко второй. Метку a можно воспринимать как наклейку, которую можно переклеивать с ящика на ящик. Когда выполняется первая строчка, интерпретатор языка Python понимает, что это целое число, и для переменной a фиксируется соответствующий тип. Но это не навсегда! После выполнения второй строки тип переменной изменится на str – строковый тип.

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

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

Иногда приведение одного типа к другому может выполняться неявно для ряда случаев, например, приведение типа int к типу double:

int v1 = 4;
double v2 = v1 + 0.123;

В этом случае, при выполнении второй строки вначале будет выполнено приведение переменной v1 к типу double, а после сложения значения v1 и числа 0.123.

А вот такой код в C# приведет к ошибке компиляции:

double v2 = "4" + 0.123;

так как “4” – это значение строкового типа, а 0.123 имеет тип double.

К языкам с сильной типизацией относятся C#, Java, Python.

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

char* str = "hello";
int value = str + 3;

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

Явная типизация предполагает явное указание типа переменной:

int value = 1;

В этом примере мы объявляем переменную value типа int и явно это указываем.

В языке с неявной типизацией этого делать не нужно, пример на Python:

value = 1 

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

double value = 0.123; 

Во втором так:

var value = 0.123;

Если Вы хотите больше узнать про язык C#, приглашаем Вас на наш курс “C#. Базовый уровень“.

Добавить комментарий

Ваш адрес email не будет опубликован.