我正在处理一些Float64函数,这些函数在其主体内部计算可以取值0.0 / 0.0的某些分数。在这种情况下,该值应解释为1.0。是否可以自动执行此操作并避免对病理病例进行编码?
Mas*_*son 11
是的,以安全的方式做到这一点非常简单,不会破坏julia或其他人的代码。
实现此目的的一种方法是在模块内部或REPL处,在显式使用/function [1]之前,只需编写
/(args...) = Base.:(/)(args...)
function /(x::Float64, y::Float64)
if x == 0.0 && y == 0.0
1.0
else
Base.:(/)(x, y)
end
end
Run Code Online (Sandbox Code Playgroud)
在代表:
julia> 1 / 2
0.5
julia> 10.0 / 0.0
Inf
julia> 0.0 / 0.0
1.0
Run Code Online (Sandbox Code Playgroud)
它的作用是隐藏内置/函数,并用您自己的自定义版本替换内置函数,而该自定义版本将落在内置函数上。这种阴影仅存在于您所在的当前模块中,并且不会泄漏到外部,除非有人明确要求您提供版本。
另一个(也许是更可取的)选择是通过unicode运算符创建一个新的中缀分割函数。这是一个例子:
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
Run Code Online (Sandbox Code Playgroud)
在REPL:
julia> 0 /? 0.0
1.0
julia> 1 /? 2
0.5
julia> 0 / 0
NaN
Run Code Online (Sandbox Code Playgroud)
之所以有效,是因为只要您将unicode修饰符(例如\hat或上标)或其他内容应用到中缀函数符号(例如/或*或其他)上,便会创建一个具有相同优先级的新infix运算符。这很好,因为我们可以保留旧的/定义,并且在除法运算符上有一个可视标记,表明正在发生某些特殊情况。
请享用!
[1]:来自Base的函数实际上只是在您第一次使用它们时才被拉到您的命名空间中,因此,如果尚未/在当前作用域中使用它,则可以随意对其进行阴影处理。否则,您将不得不通过一个let块引入一个新的作用域,并且只在/此处添加阴影。