Автоматическое растормаживание колес: Тормозные устройства колес предназначены для уменьшения длины пробега и улучшения маневрирования ВС при...
Адаптации растений и животных к жизни в горах: Большое значение для жизни организмов в горах имеют степень расчленения, крутизна и экспозиционные различия склонов...
Топ:
Оснащения врачебно-сестринской бригады.
Генеалогическое древо Султанов Османской империи: Османские правители, вначале, будучи еще бейлербеями Анатолии, женились на дочерях византийских императоров...
Когда производится ограждение поезда, остановившегося на перегоне: Во всех случаях немедленно должно быть ограждено место препятствия для движения поездов на смежном пути двухпутного...
Интересное:
Принципы управления денежными потоками: одним из методов контроля за состоянием денежной наличности является...
Влияние предпринимательской среды на эффективное функционирование предприятия: Предпринимательская среда – это совокупность внешних и внутренних факторов, оказывающих влияние на функционирование фирмы...
Средства для ингаляционного наркоза: Наркоз наступает в результате вдыхания (ингаляции) средств, которое осуществляют или с помощью маски...
Дисциплины:
2022-09-29 | 32 |
5.00
из
|
Заказать работу |
Вы можете сотворить неправильные действия с данными во время программирования, но еще более вероятно, что пользователи будут вставлять неверные данные в ваши программы во время запроса на
ввод. Создание живучего, устойчивого к ошибкам кода требует особой осторожности с пользовательским вводом данных. В следующем разделе ваша программа считывает входные данные; и вы поймете, как сделать
ее устойчивой к ошибкам, возникающим во время выполнения.
Чтобы лучше понять, как Crystal работает с типами, давайте встроим
код для чтения ввода в ту самую программу, посвященную валюте
и ее относительным курсам обмена. Начнем с чтения целых чисел в массив. Вы можете найти полный исходный код в "getting_input.cr". Консоль позволяет "подбирать" входные данные, но в Playground такого нет. Чтобы это сработало, вам нужно напечатать в терминале (ИКС):
crystal getting_input.cr
Итак, пользователь отправляет числа, а вы ожидаете, что они будут меньше 256 (в этом случае они соответствуют типу Int8):
puts "Enter the numbers one by one, and end with an empty line:"
# "Вводите числа одно за другим, и закончите ввод пустой строкой:"
arr = [] of Int8
Вы начнете с пустого массива, так как вам надо обозначить тип "[ ] of Int8". Есть и другие способы, чтобы указать тип содержимого массива, например, заполнение массива данными при инициализации:
arr1 = [75, 42, 126]
typeof(arr1) # => Array(Int32)
Почему тип определился как 'Int32', когда все эти числа меньше 127? Int32 является целочисленным типом, устанавливаемым по умолчанию. Если вы хотите установить тип Int8 — допустим, в целях повышения производительности — вы должны прописать это явным образом, примерно так:
arr1 = [75_i8, 42_i8, 126_i8]
typeof(arr1) # => Array(Int8)
(Crystal предлагает суффиксы i8, i16, i32, i64 для положительных и отрицательных целых чисел, и u8, u16, u32, u64 для беззнаковых
целых чисел.) Вы читаете с консоли с помощью gets, которая возвра-
щает все, что она читает, в виде String. Вы можете отобразить вводи-
мые в консоли данные, воспользовавшись внутристроковой вставкой.
puts "Enter a number:"
num = gets
p "You entered #{num}" # => "You entered 42"
Давайте добавим число в наш массив:
arr1 << num
Crystal не позволит вам сделать это:
Error: no overload matches 'Array(Int8)#<<' with type (String | Nil)
Теперь уже это должно восприниматься как нечто знакомое. Лучший способ выяснить, что пошло не так, это протестировать тип "num"
(первый комментарий из предыдущей некорректной строки). Вы
можете сделать это двумя способами:
p typeof(num) # => (String | Nil)
p num.class # => String
Вы видите, что Crystal делает различие между двумя понятиями:
• Тип на стадии компиляции: какой тип видит компилятор, он зада-
ется с помощью «typeof».
• Тип времени выполнения: какой тип объект имеет, когда программа уже запущена; и он определяется методом "class".
Кроме того, nil не может быть добавлен к массиву целых чисел. Но почему компилятор считает, что ввод может быть нулем (nil)? Ну
ладно, вместо ввода числа введите "CTRL+D" и посмотрите, что происходит: Тип данных для num — это Nil! Но метод '<<' не может
быть применен к нулю (nil). Вам следует остерегаться такого нулевого ввода.
Есть несколько способов сделать это. Поскольку nil противопоставлен "истине", самое простое — тестирование условным оператором if:
if num
arr << num
end
Мы пока не закончили, потому что теперь мы получаем еще одну ошибку:
«no overload matches 'Array(Int8)#<<' with type String»
Компилятор теперь знает, что num соответствует строковому (String) типу, но массив может содержать только Int8. Настало время преобразовать входные данные с помощью to_i8:
if num
arr << num.to_i8
p arr # => for example: [42]
end
Теперь Crystal преобразует строку в 8-битное целое число со знаком
(+-). Даже если строка содержит числа (т.е. арабские цифры), то да-
лее возможно несколько вариантов развития событий. Присутствие десятичной запятой приведет к ошибке, как и целые числа за
пределами диапазона от -127 до 128. Нечисловые знаки нарушат это преобразование, как именно — будет рассмотрено ниже в этой главе.
Кроме того, if работает для одиночного пользовательского ввода. Мы
не знаем, сколько чисел будет отправлено, поэтому нам потребуется
цикл. И while подходит идеально: gets самолично возвращает значение, которое может быть проверено как состояние while. Если это значение
не "ноль" или "ложь" (false), то while срабатывает нормально и
добавляет содержимое num в массив.
while num = gets
arr << num.to_i8
p arr # => for example: [2, 3, 3, 5]
end
Запомните, только nil, false или нулевые указатели считаются в Crystal ложными в любом логическом показателе или в выражениях if, unless, while и until. Любое другое значение — включая строку "false" и число 'ноль' — распознается как истина при тестировании выражений.
▪ Сокращайте выражения ▪
Основанное на правилах истинности\ложности выражение "a ||= b", которое является сокращенной формой для "a || (a = b)", используется
для присвоения b переменной a лишь в том случае, когда a равно нулю:
mem = nil
mem ||= 1
mem # 1
mem ||= "Crystal"
mem # 1
Это обычно используется в "memoization", что означает способность запечатлеть (задержать в памяти) результаты вычислений; в нашем слу-чае возвращается значение 'a', когда 'a' не равно нулю, но в противном случае возвращается b.
Возвращаясь к нашему вводу, давайте удалим все символы пробела с помощью strip, на всякий случай. Чтобы завершить цикл, проверим, вводит ли пользователь "stop" или просто ENTER, а затем прервем
цикл (break):
while num = gets
num = num.strip # removes whitespace
if num == "" || num == "stop"
break
end
arr << num.to_i8
end
p arr # => for example: [78_i8, 56_i8, 12_i8]
▪ read_line ▪
Если тестирование после gets показало, что ввод, не являясь нулевым (отличается от nil), не выглядит элегантно, вы можете также исполь-
зовать метод "read_line". Пользуйтесь им — упражнение read_line.cr показывает, как это сделать.
Археология об основании Рима: Новые раскопки проясняют и такой острый дискуссионный вопрос, как дата самого возникновения Рима...
Таксономические единицы (категории) растений: Каждая система классификации состоит из определённых соподчиненных друг другу...
Двойное оплодотворение у цветковых растений: Оплодотворение - это процесс слияния мужской и женской половых клеток с образованием зиготы...
Архитектура электронного правительства: Единая архитектура – это методологический подход при создании системы управления государства, который строится...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!