Перегрузка и многократная отправка — КиберПедия 

Индивидуальные очистные сооружения: К классу индивидуальных очистных сооружений относят сооружения, пропускная способность которых...

Своеобразие русской архитектуры: Основной материал – дерево – быстрота постройки, но недолговечность и необходимость деления...

Перегрузка и многократная отправка

2022-09-29 29
Перегрузка и многократная отправка 0.00 из 5.00 0 оценок
Заказать работу

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 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.013 с.