2016-05-13 66 views
3

我有一個模塊,我在這裏寫下:如何導入自定義模塊中的朱莉婭

# Hello.jl 
module Hello 
    function foo 
     return 1 
    end 
end 

# Main.jl 
using Hello 
foo() 

當我運行Main模塊:

$ julia ./Main.jl 

我得到這個錯誤:

ERROR: LoadError: ArgumentError: Hello not found in path 
in require at ./loading.jl:249 
in include at ./boot.jl:261 
in include_from_node1 at ./loading.jl:320 
in process_options at ./client.jl:280 
in _start at ./client.jl:378 
while loading /Main.jl, in expression starting on line 1 

回答

6

你應該include("./Hello.jl")以前using Hello

+3

那麼'使用'的意義是什麼?我認爲這個kw會包含我的模塊... – dopatraman

+0

@dopatraman'using'是將一個模塊的名字引入當前作用域,而模塊本身不會被include()'automaticlly(除了那些在「LOAD_PATH」) –

+0

如果你在'module'中有定義,你也需要導出它們。 – m33lky

0

如果你想在模塊的標題「使用」你需要添加「出口富」導入模塊時訪問函數foo。

0

除非您明確加載文件(include("./Hello.jl"))Julia會在LOAD_PATH變量中定義的目錄中查找模塊文件。

請參閱this page

6

已經有一些簡短的答案,但我想提供一個更完整的答案,如果可能的話。

當您運行using MyModule時,Julia只在名爲LOAD_PATH的目錄列表中搜索它。如果您在朱莉婭REPL鍵入LOAD_PATH,你會得到類似如下:

2-element Array{ByteString,1}: 
"/Applications/Julia-0.4.5.app/Contents/Resources/julia/local/share/julia/site/v0.4" 
"/Applications/Julia-0.4.5.app/Contents/Resources/julia/share/julia/site/v0.4" 

這些是朱莉婭將搜索模塊,當你輸入using Hello包含的目錄。在您提供的示例中,由於Hello不在您的LOAD_PATH中,Julia無法找到它。

如果您希望包含本地模塊,則可以指定其相對於當前工作目錄的位置。

julia> include("./src/Hello.jl") 

一旦包含文件,就可以正常運行using Hello以獲得所有相同的行爲。對於一個腳本,這可能是最好的解決方案。但是,如果您發現自己經常不得不include()某一組目錄,您可以永久將它們添加到您的LOAD_PATH

添加目錄LOAD_PATH

手動添加目錄到您的LOAD_PATH可以是一個痛苦,如果你想經常使用存儲的朱莉婭LOAD_PATH之外的特定模塊。在這種情況下,您可以將其他目錄附加到LOAD_PATH環境變量。每當您發出importusing命令時,Julia都會自動搜索這些目錄。

執行此操作的一種方法是將以下內容添加到您的.basrc,.profile,.zshrc

export JULIA_LOAD_PATH="/path/to/module/storage/folder" 

這會將該目錄追加到Julia將搜索的標準目錄中。如果你再運行

julia> LOAD_PATH 

它應該返回

3-element Array{ByteString,1}: 
"/path/to/module/storage/folder" 
"/Applications/Julia-0.4.5.app/Contents/Resources/julia/local/share/julia/site/v0.4" 
"/Applications/Julia-0.4.5.app/Contents/Resources/julia/share/julia/site/v0.4" 

現在,您可以自由運行using Hello和Julia會自動查找模塊(只要它被存儲下面/path/to/module/storage/folder

更多信息,請看Julia Docs的this頁面

2

雖然張實唯的回答是最接近的enient,您不應該在REPL之外使用include。如果您正在編寫程序文件,請仔細閱讀將相應目錄添加到LOAD_PATH的問題。雷米對此如何做出了很好的解釋,但也值得解釋一下爲什麼你應該這樣做。 (此外從文檔:push!(LOAD_PATH, "/Path/To/My/Module/")但要注意你的模塊和文件必須具有相同的名稱)

的問題是什麼,你include將正確的,你叫include即使是在其他地方也定義的定義。由於模塊的目標是重複使用,因此最終可能會在多個文件中使用MyModule。如果在每個文件中調用include,那麼每個文件都將有自己的MyModule定義,即使它們是相同的,這些定義也會不同。這意味着在MyModule(如數據類型)中定義的任何數據將不會相同。

爲了說明爲什麼這是一個巨大的問題,考慮這三個文件:

types.jl

module TypeModule 
struct A end 
export A 
end 

a_function.jl

include("types.jl") 
module AFunctionModule 
using TypeModule 
function takes_a(a::A) 
    println("Took A!") 
end 
export takes_a 
end 

function_caller.jl

include("a_function.jl") 
include("types.jl") 
using TypeModule, AFunctionModule 
my_a = A() 
takes_a(my_a) 

如果您運行julia function_caller.jl你會得到MethodError: no method matching takes_a(::TypeModule.A)。這是因爲function_caller.jl中使用的類型A與a_function.jl中使用的類型不同。在這種簡單的情況下,你可以通過在function_caller.jl中反轉包含的順序來實際「修復」問題(或者只需從function_caller.jl中完全刪除include("types.jl")!這不太好!)。但是如果你想要另一個文件b_function.jl,它也使用了TypeModule中定義的類型?你將不得不做一些非常冒險的事情。或者你可以修改你的LOAD_PATH,這樣該模塊只定義一次。