Тип «неизвестно»
В ряде случаев необходимо описать переменную, тип которой мы не знаем в момент написания приложения. При этом нам важно, чтобы это была конкретная переменная. От этой переменной можно вызывать какие-то методы, эта переменная может принимать участие в операциях и т. д. Но в случае языка с явной типизацией переменных, мы не можем просто описать переменную, не указывая ее типа.
В данной ситуации можно объявить переменную составного типа Объект?
. Такой тип позволит присвоить нашей переменной абсолютно любое значение, т. к. тип Объект
является базовым для любых других типов, кроме Неопределено
. А суффикс ?
позволяет присваивать в нашу переменную и значение Неопределено
. Но при таком описании переменной нам доступен только метод ПолучитьТип()
и все. Это произойдет потому, что компилятор «знает» только об этом методе.
Чтобы решить эту пробл ему, существует тип неизвестно
. Фактически, данный тип существует исключительно во время компиляции исходного текста программы. Его назначение: отключить проверку типов компилятора. Все проверки будут выполняться во время исполнения, когда станет ясно, значение какого типа размещено в переменной, объявленной с типом неизвестно
.
Сказанное выше иллюстрирует пример:
метод ТипНеизвестно()
область
пер Значение: Объект?
Значение = "Строка"
пер Результат = Значение.Длина()
;
область
пер Значение: неизвестно
Значение = "Строка"
пер Результат = Значение.Длина()
;
;
Попытка выполнить данный пример (в приведенном виде) приведет к ошибке компиляции Неизвестный метод "Объект.Длина"
в строке пер Результат = Значение.Длина()
первой области. Если эту строку закомментировать, то пример выполнится успешно.
Когда можно применять данный тип?
Допустим, у нас есть набор структур, который описывает файлы в файловой системе. Каждая структура содержит общий набор полей, например, имя файла и его тип. И для каждого типа файла есть специфический набор полей. При этом нам нужен метод, который будет принимать на вход любую из таких структур в качестве параметра и выполнять какие-то общие действия. В этом случае встает вопрос — каким образом типизировать параметр нашего метода? Можно рассмотреть вариант составного типа, но тогда при добавлении нового типа файла придется уточнить состав типов. Другой вариант — описать параметр метода с помощью типа неизвестно
.
Такой тип позволит внутри метода обращаться к свойствам параметра, «не обращая внимания» на фактический тип полученной стр уктуры. При этом во время компиляции ошибок возникать не будет, но контроль наличия свойств и методов все равно будет осуществляться во время выполнения модуля.
структура ФайлИсполнимый
пер ИмяФайла: Строка
пер ТипФайла: Строка
пер Архитектура: Число
;
структура ФайлТекстовый
пер ИмяФайла: Строка
пер ТипФайла: Строка
пер Кодировка: Строка
;
структура ФайлКонфигурационный
пер ИмяФайла: Строка
пер ТипФайла: Строка
пер Формат: Строка
;
метод Скрипт()
пер Файл1 = новый ФайлИсполнимый("util.exe", "exe", 32)
пер Файл2 = но вый ФайлТекстовый("untitled.txt", "txt", "utf-8")
пер Файл3 = новый ФайлКонфигурационный("default.vrd", "cfg", "xml")
ВыполнитьДействие(Файл1)
ВыполнитьДействие(Файл2)
ВыполнитьДействие(Файл3)
;
метод ВыполнитьДействие(Параметр: неизвестно)
пер Значение = Параметр.ТипФайла
пер Результат: Строка
выбор Значение
когда "exe"
Результат = "Архитектура исполняемого файла = %{Параметр.Архитектура}"
когда "txt"
Результат = "Кодировка текстового файла = %{Параметр.Кодировка}"
когда "cfg"
Результат = "Формат конфигурационного файла = %{Параметр.Формат}"
иначе
выбросить новый ИсключениеНедопустимыйАргумент("Неизвестный тип файла: " + Параметр.ТипФайла)
;
;
Компилятор не будет «возражать» против использования свойств от разных структур у одного параметра, т. к. параметр объявлен с типом неизвестно
. Но если во время исполнения в качестве параметра будет передано что-то совсем неожиданное для метода, будет исключение времени выполнения.
В заключении укажем еще два важных момента, которые характерны для типа неизвестно
:
- Для такого типа не существует значения типа
Тип
. ВыражениеТип(неизвестно)
не будет пропущено компилятором. - Для типа
неизвестно
не существует значения.