Да, довольно просто сделать это безопасным способом, который не нарушает код Джулии или других людей.
Один из способов добиться этого - либо внутри вашего модуля, либо в REPL, перед тем, как выкогда-либо явно использовать функцию /
[1], просто напишите
/(args...) = Base.:(/)(args...)
function /(x::Float64, y::Float64)
if x == 0.0 && y == 0.0
1.0
else
Base.:(/)(x, y)
end
end
В ответ:
julia> 1 / 2
0.5
julia> 10.0 / 0.0
Inf
julia> 0.0 / 0.0
1.0
Что это делает тени встроенный/
и заменяет ее своей собственной версией, которая отличается от встроенной.Это затенение локально только для текущего модуля, в котором вы находитесь, и не просочится наружу, если кто-то явно не попросит вашу версию.
Другой (возможно, предпочтительный) вариант - создать новую функцию разделения инфиксов с помощью операторов Юникода.,Вот пример:
function /̂(x, y) # /̂ is typed /\hat<TAB> at the REPL
if x == 0 && y == 0
one(promote_type(typeof(x), typeof(y)))
else
x / y
end
end
На REPL:
julia> 0 /̂ 0.0
1.0
julia> 1 /̂ 2
0.5
julia> 0 / 0
NaN
Это работает, потому что каждый раз, когда вы применяете модификатор юникода, такой как \hat
, или верхний индекс, или что-то еще к символу функции инфикса (как /
или *
или что-то еще) вы создаете новый инфиксный оператор с таким же приоритетом.Это хорошо, потому что мы можем сохранить старое определение /
и у нашего оператора деления есть визуальный маркер, что происходит что-то необычное.
Наслаждайтесь!
[1]: Функции из Base фактически вытягиваются в ваше пространство имен при первом их использовании, поэтому, если вы еще не использовали /
в своей текущей области видимости, вы можете затенять его.В противном случае вам нужно будет ввести новую область видимости через блок let
, и там будет затенена только /
.