consider the following example in julia
function f(x::Array{Real,1}, y::Real)
return [x..., y]
end
arr = [1,2,3]
f(arr, 4.0)
when I run this code, I get the following error
ERROR: LoadError: MethodError: no method matching f(::Array{Int64,1},
::Float64)
Closest candidates are:
f(::Array{Real,1}, ::Real) at ...
is there any way to fix this?
You should write:
function f(x::Array{<:Real,1}, y::Real)
return [x..., y]
end
This behavior is explained in this section https://docs.julialang.org/en/latest/manual/types/#Parametric-Types-1 of the Julia manual.
The problem is that Array{Float64,1}
is not a subtype of Array{Real,1}
but is a subtype of Array{<:Real,1}
.
You can check it by running the following code:
julia> Array{Float64,1} <: Array{Real,1}
false
julia> Array{Float64,1} <: Array{<:Real,1}
true
Mentally you can to read Array{<:Real,1}
as any vector whose element type specification is a subtype of Real
, while Array{Real,1}
means a vector whose element type specification is exactly Real
. Note that you can construct the latter vector, and it is sometimes useful:
julia> Real[1, 1.0]
2-element Array{Real,1}:
1
1.0
(note that 1
and 1.0
were left as-is, i.e. as int and float), whereas:
julia> [1, 1.0]
2-element Array{Float64,1}:
1.0
1.0
did the conversion of both elements to float.
Additionally the reason why Julia treats Array{Real, 1}
and Array{Float64, 1}
as subtypes of each other is that both arrays have different storage format. Array{Float64, 1}
simply stores floats (as Float64
is a concrete type) whereas Array{Real, 1}
will store pointers to arbitrary reals.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With