鍍金池/ 教程/ Java/ 模塊
類型轉(zhuǎn)換和類型提升
方法
嵌入式 Julia
交互
調(diào)用 C 和 Fortran 代碼
類型
代碼性能優(yōu)化
多維數(shù)組
元編程
函數(shù)
簡介
線性代數(shù)
與其它語言的區(qū)別
數(shù)學運算和基本函數(shù)
構造函數(shù)
控制流
常見問題
并行計算
擴展包
開發(fā)擴展包
開始
字符串
運行外部程序
變量的作用域
模塊
網(wǎng)絡和流
代碼樣式
復數(shù)和分數(shù)
可空類型
整數(shù)和浮點數(shù)
變量
日期和時間

模塊

Julia 的模塊是一個獨立的全局變量工作區(qū)。它由句法限制在 module Name ... end 之間。在模塊內(nèi)部,你可以控制其他模塊的命名是否可見(通過 import ),也可以指明本模塊的命名是否為 public(通過 export)。

下面的例子展示了模塊的主要特征。這個例子僅為演示:

    module MyModule
    using Lib

    using BigLib: thing1, thing2

    import Base.show

    importall OtherLib

    export MyType, foo

    type MyType
        x
    end

    bar(x) = 2x
    foo(a::MyType) = bar(a.x) + 1

    show(io, a::MyType) = print(io, "MyType $(a.x)")
    end

注意上述例子沒有縮進模塊體的代碼,因為整體縮進沒有必要。

這個模塊定義了類型 MyType 和兩個函數(shù)。foo 函數(shù)和 MyType 類型被 export ,因此可以被 import 進其他模塊使用。 barMyModule 的私有函數(shù)。

語句 using Lib 表明,Lib 模塊在需要時可用來解析命名。若一個全局變量在當前模塊中沒有被定義,系統(tǒng)會在 Lib export 的變量中搜索,并在找到后把它 import 進來。在當前模塊中凡是用到這個全局變量時,都會去找 Lib 中變量的定義。

語句 using BigLib: thing1, thing2using BigLib.thing1, BigLib.thing2 的縮寫。

import 關鍵字支持與 using 所有相同的語法,但只能在一個時間上對一個名稱進行操作。它不像 using 那樣會添加用于搜索的模塊。importusing 的不同之處還在于導入這一功能時必須使用新的方法擴展后的 import。

在上述的 MyModule 中我們想向標準的 show 功能增加一個方法,所以我們必須寫下 import Base.show

那些函數(shù)名只有通過 using 功能才能看到的函數(shù)是不能被擴展的。

importall 關鍵字顯式地導入導出指定模塊的所有名稱,其效果就像 import 單獨使用在它們的所有名稱一樣。

一旦一個變量是通過 usingimport 使其可見的,一個模塊就可能無法創(chuàng)建它自己的同名的變量了。輸入變量必須是只讀的;對全局變量賦值總是會影響當前模塊所擁有的變量,否則就會引發(fā)錯誤。

模塊使用方法的總結

我們要加載一個模塊時,可以使用兩個主要關鍵字:usingimport。要了解他們的差異,可以考慮下面的例子:

    module MyModule

    export x, y

    x() = "x"
    y() = "y"
    p() = "p"

    end

在這個模塊中我們(使用關鍵字 export )導出 xy 功能,也包含了非導出函數(shù) p 。我們有幾個不同的方法來加載該模塊及其內(nèi)部功能到當前工作區(qū),具體如下:

導入命令 導入變量 方法擴展可用項
using MyModule All export ed names (x and y), MyModule.x, MyModule.y and MyModule.p MyModule.x, MyModule.y and MyModule.p
using MyModule .x, MyModule.p x and p
using MyModule: x, p x and p
import MyModule MyModule.x, MyModule.y and MyModule.p MyModule.x, MyModule.y and MyModule.p
import MyModule.x, MyModule.p x and p x and p
import MyModule: x, p x and p x and p
importall MyModule All export ed names (x and y) x and y

模塊和文件

大多數(shù)情況下,文件和文件名與模塊無關;模塊只與模塊表達式有關。一個模塊可以有多個文件,一個文件也可以有多個模塊:

    module Foo

    include("file1.jl")
    include("file2.jl")

    end

在不同的模塊中包含同樣的代碼,會帶來類似 mixin 的特征??梢岳眠@點,在不同的環(huán)境定義下運行同樣的代碼,例如運行一些操作的“安全”版本來進行代碼測試:

    module Normal
    include("mycode.jl")
    end

    module Testing
    include("safe_operators.jl")
    include("mycode.jl")
    end

標準模塊

有三個重要的標準模塊:Main, Core, 和 Base。

Main 是頂級模塊,Julia 啟動時將 Main 設為當前模塊。提示符模式下,變量都是在 Main 模塊中定義,whos() 可以列出 Main 中的所有變量。

Core 包含“內(nèi)置”的所有標志符,例如部分核心語言,但不包括庫。每個模塊都隱含地調(diào)用了 using Core,因為沒有這些聲明,什么都做不了。

Base 是標準庫( 在 base/ 文件夾下)。所有的模塊都隱含地調(diào)用了 using Base,因為大部分情況下都需要它。

默認頂級聲明和裸模塊

除了 using Base,模塊顯式引入了所有的運算符。模塊還自動包含 eval 函數(shù)的定義,這個函數(shù)對本模塊中的表達式求值。

如果不想要這些定義,可以使用 baremodule 關鍵字來定義模塊。使用 baremodule 時,一個標準的模塊有如下格式:

    baremodule Mod

    using Base

    importall Base.Operators

    eval(x) = Core.eval(Mod, x)
    eval(m,x) = Core.eval(m, x)

    ...

    end

模塊的相對和絕對路徑

輸入指令 using foo, Julia 會首先在 Main 名字空間中尋找 Foo。如果模塊未找到, Julia 會嘗試 require("Foo")。通常情況下, 這會從已安裝的包中載入模塊。

然而,有些模塊還有子模塊,也就是說,有時候不能從 Main 中直接引用一些模塊。有兩種方法可以解決這個問題:方法一,使用絕對路徑,如 using Base.Sort。方法二,使用相對路徑,這樣可以方便地載入當前模塊的子模塊或者嵌套的模塊:

    module Parent

    module Utils
    ...
    end

    using .Utils

    ...
    end

模塊 Parent 包含子模塊 Utils。如果想要 Utils 中的內(nèi)容對 Parent 可見, 可以使用 using 加上英文句號。更多的句號表示在更下一層的命名空間進行搜索。例如,using ..Utils 將會在 Parent 模塊的 子模塊內(nèi)尋找 Utils 。

模塊文件路徑

全局變量 LOAD_PATH 包含了調(diào)用 require 時 Julia搜索模塊的目錄??梢杂?push! 進行擴展 :

    push!(LOAD_PATH, "/Path/To/My/Module/")

將這一段代碼放在 ~\.juliarc.jl 里能夠在每次 Julia啟動時對 LOAD_PATH 擴展。此外,還可以通過定義環(huán)境變量 JULIA_LOAD_PATH 來擴展 Julia 的模塊路徑。

小提示

如果一個命名是有許可的(qualified)(如 Base.sin),即使它沒被 export ,仍能被外部讀取。這在調(diào)試時非常有用。

import 或 export 宏時,要在宏名字前添加 @ 符號,例如 import Mod.@mac 。在其他模塊中的宏可以被調(diào)用為 Mod.@mac@Mod.mac 。

形如 M.x = y 的語法是錯的,不能給另一個模塊中的全局變量賦值;全局變量的賦值都是在變量所在的模塊中進行的。

直接在頂層聲明為 global x,可以將變量聲明為“保留”的。這可以用來防止加載時,全局變量初始化遇到命名沖突。

上一篇:復數(shù)和分數(shù)下一篇:類型