Индивидуальные очистные сооружения: К классу индивидуальных очистных сооружений относят сооружения, пропускная способность которых...
Своеобразие русской архитектуры: Основной материал – дерево – быстрота постройки, но недолговечность и необходимость деления...
Топ:
Определение места расположения распределительного центра: Фирма реализует продукцию на рынках сбыта и имеет постоянных поставщиков в разных регионах. Увеличение объема продаж...
Процедура выполнения команд. Рабочий цикл процессора: Функционирование процессора в основном состоит из повторяющихся рабочих циклов, каждый из которых соответствует...
Устройство и оснащение процедурного кабинета: Решающая роль в обеспечении правильного лечения пациентов отводится процедурной медсестре...
Интересное:
Принципы управления денежными потоками: одним из методов контроля за состоянием денежной наличности является...
Наиболее распространенные виды рака: Раковая опухоль — это самостоятельное новообразование, которое может возникнуть и от повышенного давления...
Уполаживание и террасирование склонов: Если глубина оврага более 5 м необходимо устройство берм. Варианты использования оврагов для градостроительных целей...
Дисциплины:
2022-09-29 | 29 |
5.00
из
|
Заказать работу |
|
|
Crystal позволяет вам использовать разные версии какого-либо метода под одним именем. Это называется перегрузкой. Параграф "Больше безопасности с помощью Типов" разъясняет, как можно использовать типы аргументов для ограничения методов.
Исходный код, написанный без применения типов, может быть более универсальным и повторно используемым, но недвусмысленное
указание типов может сделать исходный код гораздо более безопасным. Понимание деталей (вроде количества аргументов, их имен и способ-
ности метода принимать блок кода) поможет вам изобретать различные версии метода, которые будут работать с таким контекстом или аргументами, которые слегка отличаются от ожидаемых.
Компилятор отдельно создает исполняемый код для каждой версии метода. И если обнаруживаются запросы к общему имени такого метода, компилятор присоединяет правильную версию кода, ориентируясь на совпадения типов для успешной передачи параметров. Вы можете добиться специализации кода, опираясь на типы данных, и при этом избежать каких-либо проверок на стадии запуска на исполнение, что значительно повысит скорость выполнения вашего кода.
Чтобы увидеть это своими глазами, попробуйте сделать следующее. Скопируйте все методы "add" и тестовые работы из файла "overloading1234.cr" (см. §"Больше безопасности с помощью Типов").
Затем напишите и проверьте в работе метод add, который принимает:
• Число и логическое выражение, и возвращает это самое число, если логическое значение будет true; в противном случае будет возвращена цифра "ноль".
• Две строки, преобразует их в целые числа, а затем суммирует их (т.е. результирующим значением будет какое-то целое число).
|
Что произойдет, если выполнить программный код вышеупомянутых тестовых заданий? Используйте то, что вы усвоили из §"Обработка пользовательского ввода", чтобы разобраться с этим вопросом.
Тут есть о чем поразмыслить. После определения метода add (x:String, y:String) следует [исходный код, разрешающий тестовую ситуацию], напишем add("Hello", "Crystal"), и теперь этот новый метод будет применяться вместо традиционного метода "add".
Причина заключается в том, что типы данных в этом вызове лучше соответствуют новому методу. Но теперь "to_i" запнётся на этих аргументах, что приведет к исключительной ситуации (exception). Вы можете защитить свой новый метод от подобных сбоев:
def add(x: String, y: String)
if x.to_i? && y.to_i?
add x, y # calls version 1
end
end
Но тогда метод add("Hello", "Crystal") вернет нулевое значение (nil),
так что вам потребуется условное ветвление (else) для компенсации
этой помехи:
def add(x: String, y: String)
if x.to_i? && y.to_i?
add x, y # calls version 1
else
x + y
end
end
Ниже исходный код этого урока приведён полностью:
methods_and_procs/overloading.cr
# version 1:
def add(x: Int, y: Int)
x + y
end
# version 2:
def add(x: Number, y: Number)
x + y
end
# version 3:
def add(x: Number, y: String)
x.to_s + y # convert a number to a string with to_s method
end
# version 4:
def add(x, y)
x + y
end
# new methods:
# version 5:
def add(x: Number, y: Bool)
y? x: 0
end
# version 6:
def add(x: String, y: String)
if x.to_i? && y.to_i?
add x.to_i, y.to_i # calls version 1
else
x + y
end
end
add(2, 3) # => 5
add(1.0, 3.14) # => 4.14
add("Hello ", "Crystal") # => "Hello Crystal"
add(42, " times") # => "42 times"
add 5, true # => 5
add 13, false # => 0
add("12", "13") # => 25
Вы можете также справиться с подобной задачей, используя множественные типы (Unions) для возвращаемого значения. В новом сценарии сделайте метод add(x, y), который возвращает нулевое зна-
чение (nil), если [y равен 0], в противном случае будет возвращена
сумма [x + y].
|
Испытайте метод, записав "n = add(2, 3)". Что это за тип? Что происходит, когда вы пытаетесь выполнить n + 10?
Добавьте проверку if, чтобы предотвратить это. Когда аргументы cоответствуют множественным типам данных, компилятор не знает,
какую версию метода следует вызвать.
Только на стадии запуска выяснится реальный тип аргументов, и тогда вызовется правильная версия метода. Это называется многократной отправкой, или мульти-передачей (более точное название — "диспетчерское распределение"). Но это не слишком снижает скорость, потому что версии для всех возможных типов были скомпилированы загодя. Вы можете увидеть это ниже:
methods_and_procs/overloading3.cr
def display(x: Number) # overloading 1
puts "#{x} is a number"
end
def display(x: String) # overloading 2
puts "#{x} is a string"
end
n = 42
display n # => 42 is a number
str = "magic"
display str # => magic is a string
r = rand < 0.5? n: str
typeof(r) # => (Int32 | String)
display r
В первом методе "display" используется перегрузка вызова (1). В следующем тоже (# overloading 2), оба варианта рассматриваются во
время компиляции. Но для третьего вызова ситуация иная:
на стадии компиляции тип переменной r соответствует (Int32 | String). Какой именно тип примет "r" — станет известно только после запуска
на исполнение (из-за "rand"), и только тогда можно определить, какой
из методов display следует вызвать!
Вы можете также использовать ограничения типа для splat-аргумента, как показано ниже:
methods_and_procs/overloading3.cr
def method1(*args: Int32)
end
def method1(*args: String)
end
method1 41, 42, 43 # OK, invokes first overload
method1 "Crystal", "Ruby", "Go" # OK, invokes second overload
method1 1, 2, "No"
# Error: no overload matches 'method1' with types Int32, Int32, String
method1() # Error: no overload matches 'method1'
Обратите внимание, что последние два вызова method1 были от-
клонены компилятором.
|
|
Индивидуальные и групповые автопоилки: для животных. Схемы и конструкции...
Биохимия спиртового брожения: Основу технологии получения пива составляет спиртовое брожение, - при котором сахар превращается...
Папиллярные узоры пальцев рук - маркер спортивных способностей: дерматоглифические признаки формируются на 3-5 месяце беременности, не изменяются в течение жизни...
Археология об основании Рима: Новые раскопки проясняют и такой острый дискуссионный вопрос, как дата самого возникновения Рима...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!