Тип данных

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск

В информатике тип данных или просто тип представляет собой классификацию информационных сущностей (например, таких как значения[en] или выражения[en]), определяющую возможность их использования в рамках заданной формальной системы. Понятие имеет несколько определений, которые могут частично пересекаться или приводить к тождественныму содержанию. Наиболее принципиально различимых, хотя и не противоречащих друг другу, определений два:

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

Декларативное определение чаще всего используется в императивном программировании, процедурное — в параметрическом полиморфизме. Объектно-ориентированное программирование использует процедурное определение при описании взаимодействия компонентов программы, и декларативное — при описании реализации этих компонентов на ЭВМ, соответственно, рассматривая «класс-как-поведение» и «класс-как-объект в памяти».

Операция назначения типа информационным сущностям называется типизацией. Назначение и проверка согласования типов может осуществляться заранее (статическая типизация), непосредственно при использовании (динамическая типизация) или совмещать оба метода. Типы могут назначаться «раз и навсегда» (сильная типизация) или позволять себя изменять (слабая типизация) — см. сильная и слабая типизация.

Теория типов формально изучает типы и результаты от их назначения. Неотъемлемой частью большинства языков программирования являются системы типов, использующие типы для обеспечения той или иной степени типобезопасности[en]. Лишь немногие языки могут считаться типизированными в полной мере, большинство языков предоставляет лишь некоторый уровень типизированности.

Понятие типобезопасности[en] опирается преимущественно на процедурное определение типа. Например, попытка деления «числа» на «строку» будет отвергнута большинством языков, так как для этих типов не определено соответствующее поведение. Слабо типизированные языки тяготеют к декларативному определению. Например, «число» и «запись» имеют различное поведение, но значение[en] адреса «записи» в памяти ЭВМ может иметь то же низкоуровневое представление, что и «число». Слабо типизированные языки предоставляют возможность нарушить систему типов, назначив этому значению поведение «числа» посредством операции приведения типа. Подобные трюки могут использоваться для повышения эффективности программ, но несут в себе риск крахов[en], и поэтому не допускаются в безопасных[en] языках.

К не полным по Тьюрингу языкам описания данных (таким как SGML) процедурное определение не применимо.

Классификация[править | править исходный текст]

Существуют различные классификации типов и правил их назначения.

Например, типы делятся на примитивные и агрегатные (последние также называются составными, композитными или структурными). Примерами примитивных типов служат вещественные, целое, логическое и др. Примерами агрегатных типов служат кортежи, массивы, списки и др. Нередко встречаются также предопределённые вспомогательные типы, полезные для промышленных разработок, такие так «время», «календарная дата» и пр.

Структурные (агрегатные) типы не следует отождествлять со структурами данных: одни структуры данных непосредственно воплощаются определёнными структурными типами, но другие строятся посредством их композиции, чаще всего рекурсивной. В последнем случае говорят о рекурсивных типах данных[en]. Примером структур данных, которые почти всегда строятся посредством композиции объектов рекурсивного типа, являются бинарные деревья.

По другой классификации типы делятся на самостоятельные и зависимые. Важными разновидностями последних являются ссылочные типы, частным случаем которых, в свою очередь, являются указатели. Ссылки (в том числе и указатели) представляют собой несоставной зависимый тип, значения которого являются адресом в памяти ЭВМ другого значения. Например, в языке Си тип «указатель на целое без знака» записывается как «unsigned *», в языке ML тип «ссылка на целое без знака» записывается как «word ref».

Также типы делятся на мономорфные и полиморфные (см. переменная типа[en]).

Примеры[править | править исходный текст]

Самоприменение[править | править исходный текст]

Тип может быть параметризован другим типом, в соответствии с принципами абстракции[en] и параметричности[en]. Например, для реализации функции сортировки последовательностей нет необходимости знать все свойства составляющих её элементов — необходимо лишь, чтобы они допускали операцию сравнения. Следовательно, функция сортировки может быть определена для типа абстрактная последовательность, т.е. для информационной сущности, о которой известно лишь два существенных для этой функции свойства — наличие в ней множества индексируемых элементов и наличие операции сравнения для типа этих элементов — а все остальные свойства отвлечены от контекста (абстрагированы). Это позволит использовать одну функцию сортировки для любых последовательностей — для последовательностей целых чисел, для последовательностей строк, для последовательностей последовательностей булевых значений, и т.д. — и существенно повысит коэффициент повторного использования кода. Единообразная обработка данных разных типов называется полиморфизмом. Полиморфизм имеет несколько различных форм; в данном контексте интересен параметрический полиморфизм, вводящий понятия полиморфных типов и полиморфных функций (т.е. функций, определённых на полиморфных типах). Полиморфные (или параметрические) типы представляют собой составные типы, компонентам которых вместо конкретных типов, таких как «целое» или «массив целых», назначены абстрактные типы. Другими словами, параметрические типы представляют собой конструкторы типов, т.е. операторы над типами в арифметике типов. Аргументы этих операторов называются переменными типа[en] (англ. type variable) — они используются в определении полиморфного типа так же, как аргументы-значения в определении функции. Операторы над типами исполняются во время компиляции — это обеспечивает статическую типобезопасность[en], и при этом позволяет избежать накладных расходов, связанных с динамической типизацией. Полиморфные типы интенсивно используются в языках, типизированных по Хиндли — Милнеру, т.е. потомках языка ML.

Несмотря на очевидные преимущества параметрического полиморфизма, порой возникает необходимость обеспечивать различное поведение для разных подтипов[en] одного общего типа, либо аналогичное поведение для несовместимых типов — т.е. в тех или иных формах ad hoc полиморфизма. Однако, ему не существует математического обоснования, так что требование типобезопасности[en] долгое время затрудняло его использование. Ad hoc полиморфизм реализовывался внутри параметрически полиморфной системы типов посредством различных трюков. Для этой цели использовались либо вариантные типы[en], либо параметрические модули (функторы), либо значения, индексированные типами (англ. type-indexed value), которые, в свою очередь, также имеют ряд реализаций[1]. Классы типов[en], появившиеся в языке Haskell, предоставили более изящное решение этой проблемы.

Если рассматриваемой информационной сущностью является тип, то назначение ей типа приведёт к понятию «тип типа», или «метатип». В теории типов это понятие носит название «род типов» (англ. kind of a type или type kind). Например, род «*» включает все типы, а род «* -> *» включает все унарные конструкторы типов. Рода явным образом применяются при полнотиповом программировании — например, в виде конструкторов типов в языках семейства ML.

Расширение безопасной[en] полиморфной системы типов классами[en] и родами типов сделало Haskell первым типизированным в полной мере языком. Полученная система типов оказала влияние на другие языки (например, Scala, Agda).

Ограниченная форма метатипов присутствует также в ряде объектно-ориентированных языков в форме метаклассов. В потомках языка Smalltalk (например, Python) всякая сущность в программе является объектом, имеющим тип, который сам также является объектом — таким образом, метатипы являются естественной частью языка. В языке C++ отдельно от основной системы типов языка реализована подсистема RTTI, также предоставляющая информацию о типе в виде специальной структуры.

Использование метатипов называется отражением (а также рефлексивностью или интроспекцией).

Представление на ЭВМ[править | править исходный текст]

См.также[править | править исходный текст]

Примечания[править | править исходный текст]

Литература[править | править исходный текст]