Reputation: 81
What is the essential difference between those three different ways of declaring a function with abstract type in julia ?
Base.zero(::AbstractZero) = Zero()
Base.zero(::Type{<:AbstractZero}) = Zero()
Base.zero(::Type{T}) where T <: AbstractZero = Zero()
Upvotes: 4
Views: 237
Reputation: 144
You can also do
Base.zero(::T) where T <: AbstractZero = Zero()
similar to the first variant with the same explanation as @Bogumił Kamiński gave, that is, if you want to use the type T
within your function, that actually called the function.
Upvotes: 0
Reputation: 69829
Base.zero(::Type{<:AbstractZero}) = Zero()
and
Base.zero(::Type{T}) where T <: AbstractZero = Zero()
are almost the same. In this case they are the same.
The difference would be if you wanted to use T
in the definition of the function somewhere (as in the first case it is undefined).
To be precise:
Base.zero(::Type{<:AbstractZero}) = Zero()
expands to:
zero(::Type{var"#s1"} where var"#s1"<:AbstractZero)
but the scoping difference is neglibible.
Now the difference between:
Base.zero(::AbstractZero) = Zero()
and
Base.zero(::Type{<:AbstractZero}) = Zero()
is that the first dispatches on an object of a given type, and the second dispatches on a type itself. Here is an MWE:
julia> f(::Integer) = "integer passed"
f (generic function with 1 method)
julia> f(::Type{<:Integer}) = "integer type passed"
f (generic function with 2 methods)
julia> f(1)
"integer passed"
julia> f(Int)
"integer type passed"
Upvotes: 5