Using an imported struct as a type annotation

I have been running into a consistent problem which i assume is because i’m either trying to do something you’re not meant to do in julia, or i’m just doing it wrong.

The core of it is i am trying to put type annotations in a function, but the required type is defined in another file. Using this results in an error where the types don’t match, see MWE below.

This is a much simplified version of what i’m trying to do, i want both functions to work, but the one where i have used specialtype as a type annotation does not work. the error i get is at the bottom.

my MWE:
file1: special.jl

module special

export specialtype

using Parameters

@with_kw mutable struct specialtype
    attribute0::Int = 1
    attribute1::Float64 = 2.2
    attribute2::Float64 = 3.3
end

end #module

file2: moduleA.jl

module A

export thingA

include("./special.jl")
using .special: specialtype


function thingA(input)
    
    println("ThingA: ", input.attribute0)
    
end

end #module

file3: moduleB.jl

module B

export thingB

include("./special.jl")
using .special: specialtype


function thingB(input::specialtype)
    
    println("ThingB: ", input.attribute1)
    
end

end #module

file4: runtest.jl



include("./moduleA.jl")
using .A: thingA
include("./moduleB.jl")
using .B: thingB
include("./special.jl")
using .special: specialtype


function main()
    
    input = specialtype()
    
    thingA(input)
    thingB(input)
    
    
end
    
if abspath(PROGRAM_FILE) == @__FILE__
    main()
end

Running the test:

(ness) will@will:/MWE_gaussiansetimport$ julia runtest.jl 
ThingA: 1
ERROR: LoadError: MethodError: no method matching thingB(::specialtype)
Closest candidates are:
  thingB(::Main.B.special.specialtype) at /MWE_gaussiansetimport/moduleB.jl:9
Stacktrace:
 [1] main()
   @ /MWE_gaussiansetimport/runtest.jl:16
 [2] top-level scope
   @ /MWE_gaussiansetimport/runtest.jl:22
in expression starting at /MWE_gaussiansetimport/runtest.jl:21

Any advice on how to get this example to work, or the correct way to handle using a custom defined struct in multiple files with type annotations, would be greatly appreciated !

As a rule, don’t include the same file multiple times.

You are including special.jl in three different places, so specialtype is being defined three times. This means you have three different types that all just happen to have the same name and structure, but are distinct from the type system’s point of view.

The right way to do this is to have everything inside one top level module, include your files once, and use relative imports to get what you need out of the top level.

4 Likes

As an aside,

include("./special.jl")

is the same as:

include("special.jl")

and it is preferable to denote your type as SpecialType instead of specialtype, if you want your MWE’s to be well received. It makes it so much more obvious.

1 Like

I guess it was the case i was doing something you aren’t meant to do, thank you !