Reputation: 4137
Say I have a function where the c
keyword argument is a Union
type. Depending on the type for c
I would like to do some stuff within the function:
function foo(a :: Integer, b :: AbstractFloat; c :: Union{Integer, AbstractFloat} = nothing)
if typeof(c) <: AbstractFloat
d = c / pi
elseif typeof(c) <: Integer
d = typeof(b)(c ^ 2)
end
return d
end
Is this the correct way for dealing with this scenario? Should I instead use the multiple dispatch for a more efficient implementation? I am also thinking in terms of performance here.
Thanks.
Upvotes: 2
Views: 338
Reputation: 69939
Some comments.
This part:
c::Union{Integer, AbstractFloat} = nothing
will not compile, you would have to write c::Union{Nothing, Integer, AbstractFloat} = nothing
.
In general the typeof(c) <: AbstractFloat
should be optimized out by the compiler since the compiler knows the exact type of c
you are passing, so this style should not impact the performance of your code.
However, there are two considerations:
Union
you have to be more careful when defining methods to avoid dispatch ambiguities. Here is an example:julia> f(x::Int, y::Union{Int, Float64}) = "f1"
f (generic function with 1 method)
julia> f(x::Integer, y::Int) = "f2"
f (generic function with 2 methods)
julia> f(1, 1)
ERROR: MethodError: f(::Int64, ::Int64) is ambiguous.
which is sometimes considered as surprising (although it is a correct behavior technically)
EDIT. Here is an example when the compiler does not complain as it can always establish a more specific method:
julia> g(x::Int, y::Union{Int, Float64}) = "f1"
g (generic function with 1 method)
julia> g(x::Integer, y::Union{Int, Float64}) = "f2"
g (generic function with 2 methods)
julia> g(1, 1)
"f1"
Upvotes: 4