#function #methods #julia
#функция #методы #юлия
Вопрос:
Почему порядок определения метода отличается в этом случае? На мой взгляд, это не имеет особого смысла.
julia> f() = 1
f (generic function with 1 method)
julia> f(;arg) = 1
f (generic function with 1 method)
julia> f()
ERROR: UndefKeywordError: keyword argument arg not assigned
Stacktrace:
[1] f() at ./REPL[2]:1
[2] top-level scope at REPL[3]:1
julia> f() = 1
f (generic function with 1 method)
julia> f()
1
julia> f(arg=1)
1
Комментарии:
1. Вы сталкиваетесь с github.com/JuliaLang/julia/issues/9498 . Ожидаемое поведение здесь будет заключаться в том, что одно полностью перезаписывает другое, поэтому обычно это не должно происходить при неинтерактивном использовании
2. также смотрите docs.julialang.org/en/v1/devdocs/functions/#Keyword-arguments
3. Симеон, тебе, вероятно, следует добавить свой комментарий к ответу, поскольку это ответ. Это ошибка / особенность, зависящая от вашей перспективы, и может быть исправлена / изменена в версии 2.0, но вряд ли изменится в версии 1.x, потому что это потенциально может привести к поломке большого количества кода.
4. Я согласен, это ответ.
Ответ №1:
Порядок определения метода дает разные результаты из-за того, как функция с аргументами ключевого слова вписывается в механизм отправки метода в Julia 1.x.
Как указано в комментариях выше, короткий ответ: потому что второе определение полностью перезаписывает другое.
Но я думаю, что это не совсем точно, давайте посмотрим.
Случай 1: с порядком:
julia> f() = 2
f (generic function with 1 method)
julia> f(;arg) = 1
f (generic function with 1 method)
julia> f()
ERROR: UndefKeywordError: keyword argument arg not assigned
Определенная пользователем функция f()
переопределяется.
Случай 2: изменение порядка оба метода видны:
julia> f(;arg) = 1
f (generic function with 1 method)
julia> f() = 2
f (generic function with 1 method)
julia> f()
2
julia> f(arg=3)
1
Когда f(;arg)
значение опускается, компилятор создает метод f()
без аргументов ключевого слова
для обработки случая, когда аргументы ключевого слова не передаются.
Это приводит к двум разным результатам:
- Случай 1: созданный метод
f()
переопределяет определенный пользователемf()
. - Случай 2:
f()
определенный пользователем переопределяет созданный методf()
, ноf(;args)
остается видимым.
Обратите внимание, что в обоих случаях кажется, что в качестве конечного результата мы получаем функцию f
с 1 методом, но на самом деле во втором случае у нас фактически есть 2 функции с 1 методом каждая, одна из которых управляет определяемым пользователем f()
, а другая управляет версией аргументов ключевого f(;arg)
слова.
Полная информация о том, как опустить определение метода аргументов ключевого слова, подробно изложена в документах