Джулия: Переопределите метод для добавления функциональности

#julia #overriding

Вопрос:

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

 abstract type AbstractTask end
function complete(task::AbstractTask)
    complete_concrete_task(task)
    println("Done!")
end

struct Task <: AbstractTask
    name::String
end
complete_concrete_task(task::Task) = println(task.name)
 
 coding = Task("coding")
complete(coding)
 

В Python я бы использовал super оператор. Есть ли эквивалент в Джулии?

Заранее спасибо!

Комментарии:

1. Что плохого в таком способе сделать это? Это кажется правильным подходом. Использование invoke / super не очень идиоматично.

Ответ №1:

Я бы сказал, что использование диспетчеризации так, как вы это сделали, создает гораздо меньшую когнитивную сложность, чем вызов super . Но вы можете использовать invoke избранные методы супертипов:

 julia> abstract type AbstractTask end

julia> function complete(task::AbstractTask)
           println("Done!")
       end
complete (generic function with 1 method)

julia> struct Task <: AbstractTask
           name::String
       end

julia> complete(task::Task) = (println(task.name); invoke(complete, Tuple{AbstractTask}, task))
complete (generic function with 2 methods)

julia> coding = Task("coding")
Task("coding")

julia> complete(coding)
coding
Done!
 

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

Хорошо то, что invoke параметр с постоянным типом будет скомпилирован (по крайней мере, я так читал), так что даже накладных расходов от отправки не будет.