Значение этого типа не может быть преобразовано для передачи, так как файл не определен

Обновлено: 21.11.2024

Везде, где это возможно, Mosel отображает место, где во время компиляции была обнаружена ошибка, в формате (номер_строки/позиция_символа_в_строке).

E-100 Синтаксическая ошибка перед токеном

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

токен: ) за модом должно следовать целое число (или числовое выражение, результатом которого является целое число).
токен: запись then опущена.
token: end Должна быть добавлена ​​точка с запятой, чтобы обозначить завершение оператора, предшествующего end-if .

E-101 Несовместимые типы (type_of_problem)

Мы пытаемся применить операцию к несовместимым типам. Проверьте типы операндов.

type_of_problem: присваивание Первое присваивание определяет i как целое число, второе пытается повторно присвоить ему вещественное значение: i нужно явно объявить вещественным.
type_of_problem: cmp Значение истинности (результат 12=1 сравнивается с числовым значением.

E-102 Несовместимые типы параметров `подпрограммы'

Подпрограмма вызывается с неправильным типом параметра. Это сообщение также может отображаться вместо E-104, если подпрограмма вызывается с неправильным количеством параметров. (Это связано с возможностью перегрузки определения подпрограмм).

E-103 Неверное количество индексов для `array'(num1/num2)

Массив используется с индексами num2 вместо числа индексов num1, указанного в его объявлении.

E-104 Неверное количество параметров для `подпрограммы'(num1/num2)

Обычно отображается, если запись или чтение используются без аргументов.

E-106 Обнаружено деление на ноль

Явное деление на 0 (иначе ошибка обнаруживается только во время выполнения).

E-107 Обнаружена математическая ошибка в функции `fct'

Например, отрицательное число используется с дробной степенью.

E-108 Здесь ожидается логическое выражение

В операторе if используется что-то еще, кроме логического условия.

E-109 Попытка переопределить `name'

Объекты можно определить только один раз, изменить их тип невозможно.

E-111 Ожидается логическое выражение для оператора `op'

E-112 Для оператора `op'

ожидается числовое выражение.

op: + op: * Умножение переменных решения типа mpvar возможно только в том случае, если подходящий модуль (например, mmnl), поддерживающий не -линейные выражения загружены.

E-113 Неверный тип для преобразования

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

E-114 Неизвестный тип константы `const'

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

E-115 Выражение не может быть передано по ссылке

Мы пытаемся использовать константу там, где ожидается идентификатор. Например, в блоке инициализации можно использовать только неконстанты.

E-118 Неверный логический оператор

Логический оператор используется с типом, для которого он не определен.

W-121 Утверждение без последствий

Используется оператор, который не имеет никакого эффекта, например r += 0 .

E-122 Параметр управления `param' неизвестен

Параметры управления Mosel описаны в справочном руководстве Mosel под функцией getparam . Все параметры управления, предоставляемые модулем, например, mmxprs, можно отобразить с помощью команды EXAM , например, exam -p mmxprs . В IVE эта информация отображается браузером модуля.

E-123 `идентификатор' не определен

идентификатор используется без объявления или до его объявления. Проверьте написание имени. Если идентификатор определяется модулем, убедитесь, что соответствующий модуль загружен. Если идентификатор — это подпрограмма, определенная позже в программе, добавьте предварительное объявление в начале модели.

E-124 Выражение нельзя использовать в качестве оператора

Выражение стоит там, где ожидается утверждение. В этом случае выражение игнорируется — как правило, ограничение указано, а тип ограничения отсутствует (т.е. >= или .) или ограничение равенства возникает без переменных решения, например, 2=1 .
Эта ошибка также появляется, когда возвращаемое значение вызова функции не получено.

E-125 Ожидается выражение установки

Например, при попытке вычислить объединение целочисленной константы и набора целых чисел: union(12+)

E-126 Ожидается строковое выражение

E-127 Функция не может иметь тип `type'

Некоторые типы не могут быть возвращаемым значением функции. Обычно никакая функция не может возвращать переменную решения (типа mpvar ).

E-128 Тип `type' не имеет поля с именем `field'

Попытка доступа к неизвестному полю в записи типа.

E-129 Тип `type' не является записью

Попытка использовать разыменование записи для объекта, который не является записью. Например, используя i.j с i, определенным как целое число.

E-130 Определение типа не может быть локальным

Невозможно объявить тип в процедуре или функции.

W-131 Массив `идентификатор' не проиндексирован диапазонами: назначение может быть неверным

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

E-132 Ожидаемое выражение установки или списка

Агрегирующие операторы (такие как sum или forall ) требуют наборов или списков для описания доменов для своих циклов.

Поскольку i объявлено как целое перед циклом, выражение i=2 является логическим выражением (оно проверяет, равно ли i 2), а не определением индекса.

W-144 Символ `идентификатор' объявлен неявно

Когда модель компилируется с параметром -wi, это сообщение отображается для каждого символа, который не объявлен моделью явно.

E-147 Попытка прервать несуществующий цикл

break или next используется вне цикла.

E-148 Процедура/функция `идентификатор' объявлена, но не определена

Процедура или функции объявлены с помощью forward , но определение тела подпрограммы не найдено или тело подпрограммы не содержит оператора.

E-149 Некоторые требования не выполнены

Пакет может объявлять требования: это символы, которые должны быть объявлены моделями, использующими этот пакет. Эта ошибка возникает, когда модель использует пакет без определения всех требований.

E-150 Конец файла внутри комментария

Комментарий (обычно начинающийся с (!) не завершается. Эта ошибка может возникнуть, например, с несколькими вложенными комментариями.

E-151 Несовместимый тип для нижнего индекса num в `identifier'

Счетчик индексов num может ошибаться, если используется неправильное количество индексов.

W-152 Пустой набор для обнаруженной петли

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

E-153 Попытка присвоить индекс `idx'

Индексы цикла нельзя переназначить.

Оба этих назначения вызовут ошибку. Чтобы заменить элемент множества C , необходимо удалить этот элемент и добавить новый элемент в множество.

E-154 Неожиданный конец файла

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

E-155 Пустой `case'

Инструкция case используется без определения каких-либо вариантов.

E-156 `идентификатор' не имеет типа

Тип идентификатора не может быть определен. Как правило, необъявленному объекту назначается пустой набор.

E-157 Ожидается скалярное выражение

Оператор case можно использовать только с базовыми типами (целое, вещественное, логическое, строковое). Объявление массивов путем присваивания возможно только в том случае, если можно вывести набор индексов (например, определение массива линейных ограничений в цикле).

E-159 Опция компилятора `option' неизвестна

К допустимым параметрам компилятора относятся explterm и noimplicit . Дополнительные сведения см. в разделе Параметры директивы.

E-160 Определения функций и процедур не могут быть вложенными

Может произойти, например, если end-procedure или end-function отсутствует и следует определение второй подпрограммы.

E-161 Выражения не разрешены в качестве параметра процедуры/функции

Обычно возникает, если наборы индексов массива определены непосредственно в прототипе процедуры/функции.

Замените либо массивом (диапазон), либо массивом (набором целых чисел), либо определите A:=1..5 вне определения подпрограммы и используйте массив (A)

E-162 Здесь ожидается непустая строка

Эта ошибка возникает, например, при использовании ""

E-163 Объявления массива в форме списка не допускаются в качестве параметра процедуры/функции

Основные типы могут быть представлены в виде списка, но не массива.

W-164 Локальный символ не может быть общедоступным

E-165 Объявление `identifier' скрывает параметр

Имя параметра функции/процедуры повторно используется в локальном объявлении.

W-166 `;' отсутствует в конце оператора

Если используется опция explterm, все операторы должны заканчиваться точкой с запятой.

E-167 Оператор `op' не определен

Конструктор для типа используется в форме, которая не определена.

Модуль complex определяет конструкторы для комплексных чисел из одного или двух действительных чисел, но не из трех.

E-168 `что-то' ожидается здесь

Особый случай "синтаксической ошибки" (E-100), когда синтаксический анализатор может предположить, чего не хватает.

что-то: := Назначение обозначается := .
что-то: of of было опущено.
что-то: .. Диапазоны указаны с помощью .. .

E-169 `идентификатор' нельзя использовать в качестве имени индекса (идентификатор уже используется или объявлен)

E-170 `=' здесь ожидает скаляр (используйте `in' для набора)

Особый случай синтаксической ошибки (E-100).

E-171 [Верхняя/нижняя] граница диапазона не является целочисленным выражением

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

E-172 Здесь разрешена только ссылка на общедоступный набор

Все наборы индексов общедоступного массива также должны быть общедоступными.

E-173 Утверждение разрешено только в пакетах

Требования к блокировке можно использовать только в пакетах.

E-175 Наборы индексов типов массивов должны быть названы

Типы пользователей, определенные как массивы, должны быть проиндексированы именованными наборами (т.е. объявлены отдельно). Например, нельзя использовать диапазон или набор строк в качестве индекса такого массива.

E-176 Здесь разрешен только общедоступный тип

Если тип пользователя, зависящий от другого типа пользователя, объявлен общедоступным, вторичный тип также должен быть общедоступным. Например, если предположить, что тип T1 является закрытым, невозможно объявить T2 как общедоступный T2=набор T1 .

E-177 Неверное количество инициализаторов (n1/n2)

При встроенной инициализации (оператор :: ) количество предоставленных значений для присвоения не соответствует списку индексов.

E-202 Ожидается целочисленная константа

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

E-207 Здесь ожидается ссылка/тип проблемы

Оператор with используется с чем-то, что не является проблемой.

E-208 Может быть только один счетчик

Объявление as counter может появиться в списке итератора только один раз.

E-209 Отсутствуют индексы циклов

Обычно список итераторов содержит только объявление счетчика: необходимо указать хотя бы один индекс.

E-210 Строка, начинающаяся со строки line, не завершена

Многострочная строка неправильно заканчивается совпадающим конечным маркером.

E-211 Неверный синтаксис аннотации (игнорируется)

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

E-212 Аннотации: недопустимый путь `имя'

Некоторая часть пути, формирующая идентификатор аннотации, например, cat1.cat2 — это путь для аннотации !@cat1.cat2.name , недоступна.

E-213 Аннотации: имя `имя' не найдено

Некоторая часть пути, образующая идентификатор аннотации, например, cat1.cat2 — это путь для аннотации !@cat1.cat2.name , не определена.

E-214 Аннотации: попытка переопределить `name' (проигнорировано)

Аннотацию можно определить только один раз.

E-215 Аннотации: неверная строка определения для `имя' (значение)

Неверное или неполное объявление аннотации в операторе @mc.def, например дублирование или отсутствие свойства или значения, использование неизвестного ключевого слова. Пожалуйста, обратитесь к списку разрешенных операторов объявлений в Разделе Declaration.

E-217 Аннотации: неправильное значение `value' для `name' (ожидается: value2)

Аннотации присваивается значение, не соответствующее типу значения или набору значений, которые были указаны в ее объявлении (через @mc.def ).

E-218 Аннотации: отсутствует глава для `имя'

moseldoc пытается добавить запись документации в главу или раздел, который (еще) не определен.

Ошибки, связанные с модулями

Два разных модуля, используемых в модели, определяют один и тот же символ (несовместимые определения).

E-303 Неверный тип символа `идентификатор' из `модуль'

Внутренняя ошибка в определении пользовательского модуля (используется неизвестный тип): см. список кодов типов в справочном руководстве Native Interface.

W-306 Неизвестный оператор `op' (код num) в модуле `module'

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

E-307 Оператор `op' (код номер) из модуля `module' отклонен

Внутренняя ошибка в определении пользовательского модуля: оператор определен неправильно.

E-308 Строка параметров встроенной подпрограммы повреждена

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

W-309 Тип проблемы `typ' неизвестен: расширение `ext' игнорируется

Модуль объявляет собственный тип как проблемное расширение, но компилятор не может найти базовый тип. Например, новый тип называется "myprob.pb", но "myprob" не существует.

Ошибки, связанные с пакетами

Пакет не найден в пути к модулю (правила поиска см. в разделе Директива использует).

E-321 `файл' не является пакетом

Обычно отображается, если модель используется в качестве пакета (источник файла BIM начинается с ключевого слова model вместо package ).

E-322 Неверная версия пакета `package' (используется:num1.num2.num3/требуется:число4.число5.число6)

Модель компилируется с пакетом A в зависимости от пакета B. BIM-файл, который Mosel загрузил для B, несовместим с тем, который использовался для компиляции A (найдена версия num1.num2 .num3, требуется версия num4.num5.num6).

E-323 Пакет `package' импортирован несколько раз

Пакет нельзя импортировать в модель несколько раз. Эта ошибка обычно возникает, когда модель использует пакеты A и B, а пакет B уже включает A.

© 2001-2022 Fair Isaac Corporation. Все права защищены. Эта документация является собственностью Fair Isaac Corporation («FICO»). Получение или владение этой документацией не дает права раскрывать, воспроизводить, создавать производные работы, использовать или разрешать другим использовать ее, кроме как исключительно для целей внутренней оценки, чтобы определить, следует ли приобрести лицензию на программное обеспечение, описанное в этой документации, или как иное не указано в письменном лицензионном соглашении на программное обеспечение между вами и FICO (или аффилированным лицом FICO). Использование этой документации и описанного в ней программного обеспечения должно строго соответствовать вышеуказанным разрешенным видам использования, и никакое другое использование не разрешено.

Типы данных могут быть преобразованы в следующих случаях:

  • Когда данные из одного объекта перемещаются, сравниваются или объединяются с данными из другого объекта, может потребоваться преобразование данных из типа данных одного объекта в тип данных другого.
  • Когда данные из столбца результатов Transact-SQL, кода возврата или выходного параметра перемещаются в переменную программы, данные должны быть преобразованы из системного типа данных SQL Server в тип данных переменной.

При преобразовании между переменной приложения и столбцом набора результатов SQL Server, кодом возврата, параметром или маркером параметра поддерживаемые преобразования типов данных определяются API базы данных.

Неявное и явное преобразование

Типы данных можно преобразовывать явно или неявно.

Неявные преобразования не видны пользователю. SQL Server автоматически преобразует данные из одного типа данных в другой. Например, когда smallint сравнивается с int, smallint неявно преобразуется в int перед продолжением сравнения.

GETDATE() неявно преобразует дату в стиль 0. SYSDATETIME() неявно преобразует дату в стиль 21.

Для явных преобразований используются функции CAST или CONVERT.

Функции CAST и CONVERT преобразуют значение (локальную переменную, столбец или другое выражение) из одного типа данных в другой. Например, следующая функция CAST преобразует числовое значение $157,27 в строку символов «157,27»:

Используйте CAST вместо CONVERT, если хотите, чтобы программный код Transact-SQL соответствовал требованиям ISO. Используйте CONVERT вместо CAST, чтобы воспользоваться преимуществами стиля в CONVERT.

На следующем рисунке показаны все явные и неявные преобразования типов данных, разрешенные для системных типов данных SQL Server.К ним относятся xml, bigint и sql_variant. Неявного преобразования при присвоении типа данных sql_variant нет, но есть неявное преобразование в sql_variant.

Хотя на приведенной выше диаграмме показаны все явные и неявные преобразования, разрешенные в SQL Server, на ней не указан результирующий тип данных преобразования. Когда SQL Server выполняет явное преобразование, оператор сам определяет результирующий тип данных. Для неявных преобразований операторы присваивания, такие как установка значения переменной или вставка значения в столбец, приводят к типу данных, который был определен объявлением переменной или определением столбца. Для операторов сравнения или других выражений результирующий тип данных зависит от правил приоритета типов данных.

Например, следующий скрипт определяет переменную типа varchar , присваивает ей значение типа int, а затем выбирает конкатенацию переменной со строкой.

Целое значение 1 преобразуется в varchar , поэтому оператор SELECT возвращает значение 1 в виде строки. .

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

В этом случае инструкция SELECT выдает следующую ошибку:

Сообщение 245, уровень 16, состояние 1, строка 3. Ошибка преобразования при преобразовании значения типа varchar "не является строкой". к типу данных int.

Для оценки выражения @notastring + 'не является строкой.' , SQL Server следует правилам приоритета типов данных, чтобы завершить неявное преобразование до того, как можно будет вычислить результат выражения. Поскольку int имеет более высокий приоритет, чем varchar , SQL Server пытается преобразовать строку в целое число и терпит неудачу, поскольку эту строку нельзя преобразовать в целое число. Если выражение предоставляет строку, которую можно преобразовать, оператор выполняется успешно, как в следующем примере:

В этом случае строку 1 можно преобразовать в целочисленное значение 1 , поэтому этот оператор SELECT возвращает значение 2 . Обратите внимание, что оператор + становится сложением, а не конкатенацией, когда предоставленные типы данных являются целыми числами.

Поведение преобразования типа данных

Некоторые неявные и явные преобразования типов данных не поддерживаются при преобразовании типа данных одного объекта SQL Server в другой. Например, значение nchar нельзя преобразовать в значение изображения. Nchar может быть преобразован в двоичный только с помощью явного преобразования, неявное преобразование в двоичное не поддерживается. Однако nchar может быть явно или неявно преобразован в nvarchar.

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

Преобразование типов данных с помощью хранимых процедур автоматизации OLE

Поскольку SQL Server использует типы данных Transact-SQL, а OLE Automation использует типы данных Visual Basic, хранимые процедуры OLE Automation должны преобразовывать данные, которые передаются между ними.

В следующей таблице описаны преобразования типов данных SQL Server в Visual Basic.

< td>реальные

Все отдельные значения SQL Server преобразуются в одно значение Visual Basic, за исключением значений binary, varbinary и image. Эти значения преобразуются в одномерный массив Byte() в Visual Basic. Этот массив имеет диапазон от байта (от 0 до length 1**)**, где length — это количество байтов в двоичных значениях SQL Server, varbinary или изображениях.

Это преобразование типов данных Visual Basic в типы данных SQL Server.

В этом документе определяются распространенные проблемы преобразования типов и описываются способы их устранения в коде C++.

При написании программы на C++ важно обеспечить ее типобезопасность. Это означает, что каждая переменная, аргумент функции и возвращаемое значение функции хранит данные приемлемого типа и что операции, включающие значения разных типов, «имеют смысл» и не вызывают потери данных, неправильной интерпретации битовых комбинаций или памяти. коррупция.Программа, которая никогда явно или неявно не преобразует значения из одного типа в другой, по определению является типобезопасной. Однако иногда требуются преобразования типов, даже небезопасные преобразования. Например, вам может потребоваться сохранить результат операции с плавающей запятой в переменной типа int или передать значение в виде целого числа без знака в функцию, которая принимает целое число со знаком. Оба примера иллюстрируют небезопасные преобразования, поскольку они могут привести к потере данных или повторной интерпретации значения.

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

Неявное преобразование типов

Если выражение содержит операнды разных встроенных типов и нет явного приведения типов, компилятор использует встроенные стандартные преобразования для преобразования одного из операндов таким образом, чтобы типы совпадали. Компилятор пытается выполнить преобразования в строго определенной последовательности, пока одно из них не увенчается успехом. Если выбранное преобразование является повышением, компилятор не выдает предупреждение. Если преобразование является сужением, компилятор выдает предупреждение о возможной потере данных. Фактическая потеря данных зависит от задействованных фактических значений, но мы рекомендуем рассматривать это предупреждение как ошибку. Если задействован пользовательский тип, то компилятор пытается использовать преобразования, которые вы указали в определении класса. Если он не может найти приемлемое преобразование, компилятор выдает ошибку и не компилирует программу. Дополнительные сведения о правилах, регулирующих стандартные преобразования, см. в разделе Стандартные преобразования. Дополнительные сведения о пользовательских преобразованиях см. в разделе Пользовательские преобразования (C++/CLI).

Увеличение числа конверсий (продвижение)

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

тип данных SQL Server тип данных Visual Basic
char, varchar, text, nvarchar, ntext String
десятичный, числовой String
bit Boolean
binary, varbinary, image Одномерный массив Byte()
int Long
smallint Integer
tinyint Byte
float Double
Единые
деньги, малые деньги Валюта
datetime, smalldatetime Дата
Все, что установлено на NULL Вариант установлен на Null
< tr>
From To
Любой целочисленный тип со знаком или без знака, кроме long long или __int64 double
bool или char Любой другой встроенный тип
короткий или wchar_t int, long, long long
int, long long long
float double

Сужение числа конверсий (принуждение)

Компилятор неявно выполняет сужающие преобразования, но предупреждает вас о возможной потере данных. Отнеситесь к этим предупреждениям очень серьезно. Если вы уверены, что потери данных не произойдет, поскольку значения в большей переменной всегда будут соответствовать меньшей переменной, добавьте явное приведение, чтобы компилятор больше не выдавал предупреждение. Если вы не уверены, что преобразование безопасно, добавьте в свой код какую-либо проверку во время выполнения для обработки возможной потери данных, чтобы ваша программа не выдавала неверные результаты.

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

В следующем примере кода показаны некоторые неявные сужающие преобразования и предупреждения, которые компилятор выдает для них.

Подписанные – неподписанные конверсии

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

Обратите внимание, что значения интерпретируются в обоих направлениях. Если ваша программа выдает странные результаты, в которых знак значения кажется инвертированным по сравнению с ожидаемым, ищите неявные преобразования между целочисленными типами со знаком и без знака. В следующем примере результат выражения ( 0 - 1) неявно преобразуется из int в unsigned int при сохранении в num . Это приводит к переинтерпретации битового шаблона.

Компилятор не предупреждает о неявных преобразованиях между целочисленными типами со знаком и без знака. Поэтому мы рекомендуем вообще избегать преобразований из подписанных в неподписанные. Если вы не можете избежать их, добавьте проверку во время выполнения, чтобы определить, является ли преобразуемое значение больше или равным нулю и меньше или равным максимальному значению подписанного типа.Значения в этом диапазоне будут переведены из знакового в беззнаковое или из беззнакового в подписанное без повторной интерпретации.

Преобразования указателя

Во многих выражениях массив в стиле C неявно преобразуется в указатель на первый элемент массива, а преобразования констант могут выполняться автоматически. Хотя это удобно, это также потенциально подвержено ошибкам. Например, следующий пример плохо спроектированного кода кажется бессмысленным, и тем не менее он скомпилируется и выдаст результат «p». Во-первых, литерал строковой константы «Справка» преобразуется в char*, указывающий на первый элемент массива; этот указатель затем увеличивается на три элемента, так что теперь он указывает на последний элемент 'p'.

Явные преобразования (приведения)

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

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

Оператор приведения в стиле C идентичен оператору вызова (), поэтому он незаметен в коде и его легко не заметить. Оба плохи, потому что их трудно распознать с первого взгляда или найти, и они достаточно несопоставимы, чтобы вызвать любую комбинацию static , const и reinterpret_cast . Выяснение того, что на самом деле делает актерский состав в старом стиле, может быть трудным и подверженным ошибкам. По всем этим причинам, когда требуется приведение, мы рекомендуем вам использовать один из следующих операторов приведения C++, которые в некоторых случаях значительно более безопасны для типов и гораздо более явно выражают цель программирования:

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

Для получения дополнительной информации см. static_cast .

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

Дополнительную информацию см. в разделе dynamic_cast .

const_cast , для отбрасывания константности переменной или преобразования неконстантной переменной в константную . Отбрасывание const с помощью этого оператора так же подвержено ошибкам, как и приведение в стиле C, за исключением того, что с const_cast у вас меньше шансов выполнить приведение случайно. Иногда вам нужно отказаться от константности переменной, например, чтобы передать константную переменную функции, которая принимает неконстантный параметр. В следующем примере показано, как это сделать.

Для получения дополнительной информации см. const_cast .

reinterpret_cast , для приведения типов между несвязанными типами, такими как тип указателя и тип int .

Этот оператор приведения используется не так часто, как другие, и его переносимость на другие компиляторы не гарантируется.

В следующем примере показано, чем reinterpret_cast отличается от static_cast .

В Go типы данных используются для классификации одного конкретного типа данных, определения значений, которые можно присвоить типу, и операций, которые можно с ним выполнять. При программировании бывают случаи, когда вам нужно преобразовать значения между типами, чтобы манипулировать значениями по-другому. Например, может потребоваться объединить числовые значения со строками или представить десятичные разряды в числах, которые были инициализированы как целые значения. Пользовательским данным часто автоматически присваивается строковый тип данных, даже если они состоят из чисел; чтобы выполнять математические операции с этим вводом, вам нужно преобразовать строку в числовой тип данных.

Поскольку Go является статически типизированным языком, типы данных привязаны к переменным, а не к значениям. Это означает, что если вы определяете переменную как int, она может быть только int; вы не можете присвоить ему строку без преобразования типа данных переменной.Статическая природа типов данных в Go придает еще большее значение изучению способов их преобразования.

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

Преобразование типов чисел

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

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

Преобразование между целочисленными типами

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

Предположим, что у вас есть int8 и вам нужно преобразовать его в int32. Вы можете сделать это, заключив его в преобразование типа int32():

В этом блоке кода index определяется как тип данных int8, а bigIndex — как тип данных int32. Чтобы сохранить значение index в bigIndex, он преобразует тип данных в int32. Это делается путем переноса преобразования int32() на переменную index.

Чтобы проверить типы данных, вы можете использовать оператор fmt.Printf и глагол %T со следующим синтаксисом:

Поскольку здесь используется команда %T, оператор печати выводит тип переменной, а не фактическое значение переменной. Таким образом, вы можете подтвердить преобразованный тип данных.

Вы также можете преобразовать целое число большего битового размера в целое число меньшего битового размера:

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

Преобразование целых чисел в числа с плавающей запятой

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

Этот код объявляет переменную x типа int64 и инициализирует ее значение равным 57 .

Обертывание преобразования float64() вокруг x приведет к преобразованию значения 57 в значение с плавающей запятой 57,00 .

Глагол печати %.2f указывает fmt.Printf форматировать число с двумя десятичными знаками.

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

Используя float32() или float64(), вы можете преобразовывать целые числа в числа с плавающей запятой. Далее вы узнаете, как преобразовывать числа с плавающей запятой в целые числа.

Преобразование чисел с плавающей запятой в целые

Go может преобразовывать числа с плавающей запятой в целые, но программа потеряет точность числа с плавающей запятой.

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

Этот синтаксис преобразует число с плавающей запятой 390,8 в целое число 390 с отбрасыванием десятичного разряда.

Вы также можете использовать это с переменными. Следующий код объявляет b равным 125,0 и c равным 390,8 , а затем выводит их как целые числа. Краткое объявление переменной ( := ) сокращает синтаксис:

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

Числа, преобразованные делением

При делении целочисленных типов в Go результатом также будет целочисленный тип с отброшенным модулем или остатком:

Если при делении какой-либо из типов чисел является числом с плавающей запятой, то все типы автоматически будут объявлены как числа с плавающей запятой:

Это число с плавающей запятой 5,0 делится на целое число 2 , и ответ 2,5 представляет собой число с плавающей запятой, сохраняющее десятичную точность.

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

Преобразование строк

строка — это последовательность из одного или нескольких символов (букв, цифр или символов). Строки — это распространенная форма данных в компьютерных программах, и вам может потребоваться довольно часто преобразовывать строки в числа или числа в строки, особенно когда вы принимаете данные, созданные пользователями.

Преобразование чисел в строки

Числа можно преобразовать в строки с помощью метода strconv.Itoa из пакета strconv стандартной библиотеки Go. Если вы передадите число или переменную в круглые скобки метода, это числовое значение будет преобразовано в строковое значение.

Сначала рассмотрим преобразование целых чисел. Чтобы преобразовать целое число 12 в строковое значение, вы можете передать 12 в метод strconv.Itoa:

При запуске этой программы вы получите следующий вывод:

Кавычки вокруг числа 12 означают, что число больше не является целым числом, а теперь является строковым значением.

Вы использовали оператор присваивания := как для объявления новой переменной с именем a, так и для присвоения значения, возвращаемого функцией strconv.Itoa(). В этом случае вы присвоили своей переменной значение 12. Вы также использовали команду %q в функции fmt.Printf, которая указывает функции заключать предоставленную строку в кавычки.

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

При запуске этого кода вы получите следующую ошибку:

В Go нельзя объединять строки и целые числа, поэтому вам придется преобразовать переменные строки в строковое значение:

Теперь, когда вы запустите код, вы получите следующий вывод, который поздравляет вашего пользователя с прогрессом:

Если вы хотите преобразовать число с плавающей запятой в строку, а не целое число в строку, выполните аналогичные шаги и формат. Когда вы передаете число с плавающей запятой в метод fmt.Sprint из пакета fmt в стандартной библиотеке Go, будет возвращено строковое значение числа с плавающей запятой. Вы можете использовать либо само значение с плавающей запятой, либо переменную:

Вы можете проверить правильность, объединив строку:

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

Преобразование строк в числа

Строки можно преобразовать в числа с помощью пакета strconv стандартной библиотеки Go. В пакете strconv есть функции для преобразования как целых чисел, так и чисел с плавающей запятой. Это очень распространенная операция при приеме ввода от пользователя. Например, если у вас есть программа, запрашивающая возраст человека, когда он вводит ответ, он фиксируется в виде строки. Затем вам нужно будет преобразовать его в int, чтобы выполнить с ним какие-либо математические операции.

Если в вашей строке нет десятичных разрядов, вы, скорее всего, захотите преобразовать ее в целое число с помощью функции strconv.Atoi. Если вы знаете, что будете использовать число как число с плавающей запятой, вы должны использовать strconv.ParseFloat .

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

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

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

Поскольку строка может не быть числом, метод strconv.Atoi() вернет как преобразованный тип, так и возможную ошибку. При преобразовании из lines_yesterday с помощью функции strconv.Atoi вы должны проверить возвращаемое значение err, чтобы убедиться, что значение было преобразовано. Если ошибка не равна nil , это означает, что strconv.Atoi не удалось успешно преобразовать строковое значение в целое число. В этом примере вы использовали оператор if для проверки наличия ошибки, и если ошибка была возвращена, вы использовали log.Fatal для регистрации ошибки и выхода из программы.

Запустив предыдущий код, вы получите:

Теперь попробуйте преобразовать строку, которая не является числом:

Вы получите следующую ошибку:

Поскольку b было объявлено, но strconv.Atoi не смог выполнить преобразование, значение b так и не было присвоено. Обратите внимание, что b имеет значение 0 . Это связано с тем, что в Go есть значения по умолчанию, называемые в Go нулевыми значениями. strconv.Atoi также выдает ошибку, объясняющую, почему не удалось преобразовать строку.

Преобразование строк и байтов

Строки в Go хранятся в виде фрагментов байтов. В Go вы можете преобразовать фрагмент байтов в строку, обернув его соответствующими преобразованиями []byte() и string() :

Здесь вы сохранили строковое значение в a , затем преобразовали его в срез байтов b , а затем преобразовали срез байтов обратно в строку как c . Затем вы выводите a , b и c на экран:

Первая строка вывода — это исходная строка my string . Вторая напечатанная строка — это байтовый срез, из которого состоит исходная строка. Третья строка показывает, что байтовый срез можно безопасно преобразовать обратно в строку и распечатать обратно.

Заключение

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

Если вам нужен более глубокий анализ типов данных в Go, ознакомьтесь с нашей статьей «Понимание типов данных в Go».

Хотите узнать больше? Присоединяйтесь к сообществу DigitalOcean!

Присоединяйтесь к нашему сообществу DigitalOcean, насчитывающему более миллиона разработчиков, бесплатно! Получайте помощь и делитесь знаниями в нашем разделе "Вопросы и ответы", находите руководства и инструменты, которые помогут вам расти как разработчику и масштабировать свой проект или бизнес, а также подписывайтесь на интересующие вас темы.

Серия руководств: Как программировать на Go

Go (или GoLang) – это современный язык программирования, первоначально разработанный Google, в котором используется высокоуровневый синтаксис, аналогичный языкам сценариев. Он популярен благодаря минимальному синтаксису и инновационной обработке параллелизма, а также инструментам, которые он предоставляет для создания собственных двоичных файлов на иностранных платформах.

Читайте также: