Вызовите более общий метод из конкретного

#julia

#julia

Вопрос:

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

 function fn(x)
  # generic
  ...
end

function fn(x :: String)
  # I want to call the generic version here
  val = fn(x)
  # do something with val and then return it
  ...
end
 

Возможно ли это?

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

 function helper(x)
  # main work is here
  ...
end

function fn(x)
  # generic
  helper(x)
end

function fn(x :: String)
  val = helper(x)
  # now use the val to do something
  ...
end
 

Есть ли способ управлять отправкой без использования таких помощников, чтобы выбрать конкретный метод для использования? Есть ли в Julia что-то вроде :before :after ключевых слов and и call-next-method из lisp CLOS?

Ответ №1:

Вы можете использовать invoke функцию:

 julia> function fn(x)
         @info "generic $x"
       end
fn (generic function with 1 method)

julia> function fn(x :: String)
         @info "before"
         invoke(fn, Tuple{Any}, x)
         @info "after"
       end
fn (generic function with 2 methods)

julia> fn(10)
[ Info: generic 10

julia> fn("10")
[ Info: before
[ Info: generic 10
[ Info: after
 

(просто для ясности — печать "before" и "after" предназначена только для выделения того, что выполняется в какой последовательности — единственное, что связано с отправкой метода здесь, это invoke функция)

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

1. Обратите внимание, что, хотя вы можете это сделать, этот helper метод, вероятно, является гораздо лучшим решением.

2. да, и этот шаблон очень часто используется в Julia.

3. Чаще всего вы бы использовали invoke , если вам нужно вызвать определенный метод в модуле, которым вы не владеете.