Type checking seems to be off within structs when it comes to Arrays and UnitRanges. Defining a function with an argument that is of type Array forbids supplying a UnitRange as an input. However, when a struct is defined with one of its fields as an Array, it allows populating it with a UnitRange. Is this the intended behavior?
As an example:
#define a function
f(x::Array) = x
#define a struct
struct F
x::Array
end
display(f(1:3))
display(F(1:3))
f(1:3) gives a MethodError, whereas F(1:3) is acceptedβ¦
This is behaving as expected. No conversion is done upon calling functions unless you define the methods that do the conversions.
When you define a struct without an inner constructor, Julia helpfully defines the constructor methods that do the conversion for you. You can turn this off by supplying an inner constructor.
julia> struct F
x::Array
end
julia> methods(F)
# 2 methods for type constructor:
[1] F(x::Array) in Main at REPL[1]:2
[2] F(x) in Main at REPL[1]:2
julia> @which F(1:3)
F(x) in Main at REPL[1]:2
julia> @code_lowered F(1:3)
CodeInfo(
1 β %1 = Main.F
β %2 = Core.fieldtype(%1, 1)
β %3 = Base.convert(%2, x)
β %4 = %new(%1, %3)
βββ return %4
)
2 Likes