0Pricing
Lua Academy · Урок

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

Изучите автоматическое приведение строк и чисел, а также явные вызовы tonumber и tostring.

«Приведение и преобразование типов» — бесплатный урок Lua Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.

Что такое приведение типов?

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

В отличие от JavaScript, приведение типов в Lua ограничено и предсказуемо. Логические значения не преобразуются автоматически в числа, а таблицы — в строки.

-- String to number (arithmetic context)
print("10" + 5)     -- 15  (coerced)
print("3.14" * 2)   -- 6.28

-- Number to string (concatenation context)
print(10 .. "px")   -- 10px
print(3.14 .. "!")  -- 3.14!

-- No boolean coercion
-- print(true + 1)  -- ERROR!

Правила приведения строки к числу

Когда строка появляется в арифметическом выражении, Lua пытается преобразовать её в число. Если строка не представляет допустимое число, возникает ошибка во время выполнения. Допустимые числовые строки включают целые числа ("42"), числа с плавающей точкой ("3.14"), шестнадцатеричные числа ("0xff") и экспоненциальную запись ("1e3").

Строки с пробелами в начале или конце принимаются: Lua удаляет эти пробелы при приведении типов.

print("42" + 0)      -- 42    (integer)
print("3.14" + 0)    -- 3.14  (float)
print("0xff" + 0)    -- 255   (hex)
print("  10  " + 0)  -- 10    (whitespace ok)
print("1e3" + 0)     -- 1000.0

-- This will error:
-- print("hello" + 0)  -- attempt to perform arithmetic on a string value

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

При объединении числа с помощью .. Lua автоматически преобразует число в строку. Целые числа преобразуются в десятичное представление, а у чисел с плавающей точкой могут появиться десятичные знаки. Для точного управления форматом всегда используйте tostring() или string.format(), а не полагайтесь на неявное приведение типов.

print(10 .. "!")       -- 10!
print(3.14 .. "!")     -- 3.14!
print(1/3 .. "!")      -- 0.33333333333333!

-- Explicit is better for precision
print(string.format("%.2f", 1/3))  -- 0.33
print(tostring(10))                -- 10
print(tostring(10.0))              -- 10.0

tonumber(): явное преобразование

tonumber(v) явно преобразует значение в число. При успешном преобразовании функция возвращает полученное число, а при неудаче — nil; ошибка при этом не возникает. Для разбора целых чисел можно указать основание системы счисления от 2 до 36, что позволяет преобразовывать двоичные, восьмеричные и шестнадцатеричные числа.

При обработке пользовательского ввода всегда проверяйте возвращаемое значение tonumber() на равенство nil.

print(tonumber("42"))      -- 42
print(tonumber("3.14"))    -- 3.14
print(tonumber("0xFF"))    -- 255
print(tonumber("hello"))   -- nil (no error!)
print(tonumber(true))      -- nil

-- Base conversion
print(tonumber("ff", 16))  -- 255
print(tonumber("11", 2))   -- 3   (binary)
print(tonumber("77", 8))   -- 63  (octal)

tostring(): явное преобразование

tostring(v) преобразует любое значение в строку. Для чисел функция создаёт строку в десятичной или экспоненциальной записи. Для логических значений она создаёт "true" или "false". Для nil возвращается "nil". Для таблиц и функций возвращается адрес, например "table: 0x...", если не определён метаметод __tostring.

print(tostring(42))         -- 42
print(tostring(3.14))       -- 3.14
print(tostring(true))       -- true
print(tostring(false))      -- false
print(tostring(nil))        -- nil
print(tostring({}))         -- table: 0x...

-- Useful for safe concatenation
local val = nil
local msg = "Value: " .. tostring(val)
print(msg)   -- Value: nil

math.tointeger()

math.tointeger(x) (Lua 5.3+) преобразует число с плавающей точкой в целое только при наличии точного целого представления. Если преобразование приведёт к потере точности, функция возвращает nil. Это безопаснее, чем math.floor(), которая всегда завершается успешно, но может незаметно отбросить дробную часть.

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

print(math.tointeger(5.0))   -- 5   (exact)
print(math.tointeger(5.5))   -- nil (not exact)
print(math.tointeger(2^53))  -- 9007199254740992

-- Contrast with math.floor
print(math.floor(5.9))       -- 5   (truncates)
print(math.floor(5.0))       -- 5

-- Check before use
local n = math.tointeger(val) or error("need integer")

Приведение типов при сравнении

Lua не приводит типы при сравнении на равенство. Выражение 1 == "1" всегда равно false, поскольку операнды имеют разные типы. Однако операторы отношений (<, > и т. д.) инициируют приведение между строками и числами, но только если оба операнда имеют один и тот же тип. Смешивание типов при сравнении порядка вызывает ошибку.

print(1 == "1")    -- false (no coercion)
print(1 == 1.0)    -- true  (int/float equal)

-- Ordering: same type only
print("abc" < "abd")  -- true (string compare)
print(1 < 2)          -- true (number compare)

-- This ERRORS: mixing string and number
-- print(1 < "2")  -- attempt to compare number with string

Практика: разбор пользовательского ввода

В программах на Lua очень часто строку из пользовательского ввода (например, полученную с помощью io.read()) преобразуют в число. Всегда используйте tonumber() и проверяйте результат на nil, чтобы корректно обрабатывать неверный ввод, а не допускать аварийного завершения программы.

-- Safe input parsing pattern
local function parseNumber(input)
  local n = tonumber(input)
  if n == nil then
    return nil, "Invalid number: " .. tostring(input)
  end
  return n, nil
end

local val, err = parseNumber("42")
print(val, err)   -- 42  nil

local val2, err2 = parseNumber("abc")
print(val2, err2) -- nil  Invalid number: abc

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

Числа с плавающей точкой имеют ограниченную точность. Операции, в которых смешиваются целые числа и числа с плавающей точкой, могут давать неожиданные результаты из-за представления IEEE 754. Максимальное целое число, точно представимое в формате double, равно 2^53 = 9,007,199,254,740,992. При хранении в виде числа с плавающей точкой целые числа, превышающие это значение, теряют точность.

В Lua 5.3+ встроенные 64-разрядные целые числа точно поддерживают значения до 2^63-1, то есть значительно большие. Если точность важна, всегда используйте целочисленную арифметику.

-- Float precision limit
print(2^53)            -- 9.007...e+15
print(2^53 + 1 == 2^53) -- true (precision lost!)

-- Integer stays exact
local big = math.maxinteger
print(big)             -- 9223372036854775807
print(math.type(big))  -- integer

-- Mixing promotes to float
print(math.type(1 + 1.0))  -- float

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

string.format() — самый мощный инструмент для преобразования числа в строку, когда требуется управлять точностью, дополнением и представлением. Функция использует спецификаторы формата C printf. Применяйте её для отображения, вывода в файл и везде, где стандартного представления tostring() недостаточно.

print(string.format("%d", 255))      -- 255
print(string.format("%x", 255))      -- ff
print(string.format("%05d", 42))     -- 00042
print(string.format("%.2f", 3.14159)) -- 3.14
print(string.format("%e", 12345.0))  -- 1.234500e+04
print(string.format("%s=%d", "x", 10)) -- x=10

Быстрая проверка

Что возвращает tonumber("hello") в Lua?

Повторение: приведение типов и преобразование

Что Вы узнали:

  • Lua автоматически преобразует строки в числа в арифметических выражениях, а числа — в строки при конкатенации
  • tonumber() возвращает nil при неудаче — всегда проверяйте результат!
  • tostring() безопасно преобразует любое значение в строку
  • Равенство (==) никогда не приводит типы — значения разных типов не могут быть равны
  • Используйте string.format() для точного форматирования чисел
  • Предел точности чисел с плавающей точкой — 2^53; для больших точных значений используйте встроенные целые числа

Далее: управление выполнением с помощью if/elseif/else и циклов.

Часто задаваемые вопросы

Урок «Приведение и преобразование типов» бесплатный?

Да — полный текст урока «Приведение и преобразование типов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.

Чему я научусь в уроке «Приведение и преобразование типов»?

Изучите автоматическое приведение строк и чисел, а также явные вызовы tonumber и tostring. Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Lua Academy?

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

Сколько времени занимает урок «Приведение и преобразование типов»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Lua Academy?

Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Обзор типов данных Lua
  2. Объявление переменных в Lua
  3. Арифметические и реляционные операторы
  4. Приведение и преобразование типов
← Назад к Lua Academy