#module #julia
#модуль #julia
Вопрос:
Я был озадачен тем, как определить и использовать пользовательский module
интерфейс в Julia.
Например, я определил module
named myMoldule
для переноса изменяемой структуры Param
и функции add
в D:\run\defineModule.jl
:
module myMoldule
export Param, add
mutable struct Param
x ::Int64
y ::Int64
end
function add(x::Int64, y::Int64)
sum ::Int64
sum = x y
return sum
end
end
и использовал этот модуль в D:\run\useModule.jl
подобном:
include("D:\run\defineModule.jl")
using .myMoldule
function testModule()
param = Param(1, 2)
sum = add(param.x, param.y)
println(sum)
end
Произошла ошибка при выполнении testModule()
следующего:
julia> testModule()
ERROR: UndefVarError: Param not defined
Stacktrace:
[1] testModule() at D:runuseModule.jl:8
[2] top-level scope at none:1
Обратите внимание, что я использовал абсолютный путь в include(...)
, чтобы избежать использования LOAD_PATH
материала, и добавил .
перед именем модуля (т. Е. using .myMoldule
).
В чем, по-видимому, проблема?
PS: информация о версии Julia:
julia> versioninfo()
Julia Version 1.5.2
Commit 539f3ce943 (2020-09-23 23:17 UTC)
Platform Info:
OS: Windows (x86_64-w64-mingw32)
CPU: Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-9.0.1 (ORCJIT, skylake)
Environment:
JULIA_DEPOT_PATH = C:Usersf.julia;C:optJuliaPro-1.5.2-1Julia-1.5.2localsharejulia;C:optJuliaPro-1.5.2-1Julia-1.5.2sharejulia
JULIA_LOAD_PATH = @;@v#.#;@stdlib
JULIA_NUM_THREADS = 6
JULIA_PKG_SERVER = pkg.juliahub.com
Ответ №1:
Необходимо внести исправления:
sum
является ли функция, вBase
которой вы должны использовать другое имя- нет необходимости объявлять
sum
переменную (и она должна быть названа примерно такmysum
) - Удалите пробел перед
::
- Имена модулей должны начинаться с заглавной буквы
- У вас опечатка в имени модуля возможно, вы загружаете другой модуль, чем вы думаете?
После исправления ваш код работает.
Комментарии:
1. Я исправил все проблемы, на которые указал Пшемыслав Шуфель. Я обнаружил, что к ошибке приводит не то, как я назвал
sum
или модульUndefVarError: Param not defined
.2. Небольшое уточнение для читателей: пробелы разрешены
::
и могут быть полезны для удобства чтения при определенииstructs
. 🙂
Ответ №2:
Проблема возникает из-за того, что вы используете .MyModule1
, а не в MyModule2
, и, следовательно, вы импортируете Param
в основной модуль, но не в MyModule2
, поэтому Module2 не видит Param
.
Если вы поставите using ..MyModule1
(две точки вместо одной, так как у вас есть еще один уровень), MyModule2
эта проблема исчезнет.
Однако ваш код все равно не будет работать, поскольку include
функция julia просто запускает все содержимое включенного файла, таким образом, даже если вы включили один и тот же файл, вы создадите разные экземпляры модулей. Это предупреждение WARNING: replacing module...
указывает на то, что где-то в вашем коде вы можете использовать другую версию модуля (в вашем случае Main.Module1 и Main.Module2.Module1).
Обычной практикой в Julia является включение всех файлов в одном месте (они должны быть включены только один раз). Например, вы можете поместить все включения в файл useModule.jl
:
include("./defineModule1.jl")
include("./defineModule2.jl")
using .MyModule1
using .MyModule2
function testModule()
param = Param(1, 2)
# call myAdd to get the sum of param.x and param.y
sumValue = myAdd(param)
println(sumValue)
# call mySubtract to get the difference of param.x and param.y
difValue = mySubtract(param)
println(difValue)
end
Не включайте файлы в другие места. например
defineModule2.jl
, содержимое:
module MyModule2
using ..MyModule1
export myAdd, mySubtract
function myAdd(param::Param)
return param.x param.y
end
function mySubtract(param::Param)
return param.x - param.y
end
end # end of module
Ответ №3:
Примечание участника: следующий новый вопрос, который был отклонен (возможно), был расширен до исходного, и на него хорошо ответил Виталий Яковчук.
Я исправил все проблемы, на которые указал Пшемыслав Шуфель. В моем случае выше проблема не в неправильных способах именования.
Теперь у меня есть лучший пример, чтобы прояснить мою проблему.
Предположим, что для удовлетворения потребностей мне нужно разделить исходный код Julia на два модуля, например, определить изменяемую структуру Param
в defineModule1.jl
и определить функции в defineModule2.jl
. Сценарии кода следующие:
"D:\run\defineModule1.jl"
:
module MyModule1
export Param
mutable struct Param
x::Int64
y::Int64
end
end # end of module
"D:\run\defineModule2.jl"
:
include("D:\run\defineModule1.jl"); using .MyModule1
module MyModule2
export myAdd, mySubtract
function myAdd(param::Param)
return param.x param.y
end
function mySubtract(param::Param)
return param.x - param.y
end
end # end of module
Обратите внимание, что Param
это здесь не определено, и для обеспечения Param
доступности include("D:\run\defineModule1.jl"); using .MyModule1
в качестве первой строки этого файла добавляется строка.
"D:\run\useModule.jl"
:
include("D:\run\defineModule1.jl"); using .MyModule1
include("D:\run\defineModule2.jl"); using .MyModule2
function testModule()
param = Param(1, 2)
# call myAdd to get the sum of param.x and param.y
sumValue = myAdd(param)
println(sumValue)
# call mySubtract to get the difference of param.x and param.y
difValue = mySubtract(param)
println(difValue)
end
Обратите внимание, что как в функции myAdd(param)
, так и mySubtract(param)
в скрипте defineModule2.jl
требуется предопределенная изменяемая структура Param
defineModule1.jl
.
Это то, что я получил при запуске D:\run\useModule.jl
:
julia> include("D:\run\useModule.jl")
WARNING: replacing module MyModule1.
WARNING: replacing module MyModule1.
WARNING: replacing module MyModule2.
ERROR: LoadError: LoadError: UndefVarError: Param not defined
Stacktrace:
[1] top-level scope at D:rundefineModule2.jl:7
[2] include(::String) at .client.jl:457
[3] top-level scope at D:runuseModule.jl:2
[4] include(::String) at .client.jl:457
[5] top-level scope at none:1
in expression starting at D:rundefineModule2.jl:7
in expression starting at D:runuseModule.jl:2
Я полагал, что, используя следующие строки в начале «D:runuseModule.jl «, изменяемая структура Param
должна была быть найдена:
include("D:\run\defineModule1.jl"); using .MyModule1
include("D:\run\defineModule2.jl"); using .MyModule2
...
Тем не менее, LoadError: UndefVarError: Param not defined
сообщается об ошибке.
Итак, почему не может Param
быть найдено D:\run\useModule.jl
?