Seanny123
Seanny123

Reputation: 9346

Importing typed functions

I can't seem to import a function with typed arguments. Luckily, I have a minimal failing example.

Given a Query defined in structs.jl:

module Structs

export Query

struct Query
    name::String
    data::Int
end

end

And a simple function dist which uses this type:

module Utils

include("structs.jl")
using .Structs: Query

export dist

function dist(x::Query, y::Query)
    return (x.data - y.data) ^ 2
end

end

Why can dist not be found, when I call it in import_test.jl?

include("structs.jl")
using .Structs: Query

include("utils.jl")
using .Utils: dist

a = Query("a", 1)
b = Query("b", -1)

println(dist(a, b))

Instead, it fails with the error:

ERROR: LoadError: MethodError: no method matching dist(::Query, ::Query)
Stacktrace:
 [1] top-level scope at none:0
 [2] include at .\boot.jl:317 [inlined]
 [3] include_relative(::Module, ::String) at .\loading.jl:1041
 [4] include(::Module, ::String) at .\sysimg.jl:29
 [5] exec_options(::Base.JLOptions) at .\client.jl:229
 [6] _start() at .\client.jl:421
in expression starting at C:\Users\mr_bo\julia_test\import_test.jl:13

However, if I remove the types from the dist function, such that it becomes function dist(x, y), the error no longer occurs.

Am I import the Query type/struct incorrectly?

Upvotes: 2

Views: 133

Answers (1)

Bogumił Kamiński
Bogumił Kamiński

Reputation: 69879

The problem is that you define module Query twice and those are two distinct modules. Then Query from one module is not the same as Query from the other module.

You can define what you want like this (I am giving an example without include statements, but you could introduce them to get the same effect):

module Structs

export Query

struct Query
    name::String
    data::Int
end

end

module Utils

using ..Structs: Query

export dist

function dist(x::Query, y::Query)
    return (x.data - y.data) ^ 2
end

end

using .Structs: Query
using .Utils: dist

a = Query("a", 1)
b = Query("b", -1)
println(dist(a, b))

Now you might say that you want structs.jl and utils.jl files to live independently. Then you should make a package out of structs.jl and then you can load it in utils.jl inside a module as well as in import_test.jl in outer scope and Julia will know that Query is the same definition. The steps to achieve this are described here in the Julia manual.

Upvotes: 3

Related Questions