Nim語言的模組化程式設計

liulun發表於2015-08-07

前言

Nim支援把一大段程式分成若干個模組

一個模組就是一個原始碼檔案

每個模組都擁有它自己的名稱空間

模組化可以起到封裝(資訊隱藏)和分步編譯的作用

 

一個模組可以通過import語句獲得另一個模組的符號

nim語言允許模組間的迴圈引用,

只有用星號(*)標記的頂級符號才會被匯出給其他模組。

模組名和檔名相同,模組名的命名方式和nim程式語言的識別符號命名方式相同

 

編譯器編譯模組的規則如下:

  • 按照import的匯入順序,編譯模組

  • 如果存在迴圈引用,那麼就只匯入頂級符號(已解析的符號),如果編譯器發現未知的識別符號,那麼就停止編譯

請看下面的例子:

模組A的程式碼:

# Module A
type
  T1* = int  # Module A exports the type ``T1``
import B     # the compiler starts parsing B

proc main() =
  var i = p(3) # works because B has been parsed completely here

main()

模組B的程式碼:

# Module B
import A  # A is not parsed here! Only the already known symbols
          # of A are imported.

proc p*(x: A.T1): A.T1 =
  # this works because the compiler has already
  # added T1 to A's interface symbol table
  result = x + 1

看起來是不是很厲害呢?!

 

import語句

可以通過import匯入一個或多個模組

(匯入多個模組的話,只要在import後面跟上模組的名字即可,模組的名字用逗號隔開)

可以用except排除一個或多個模組中的符號

請看下面的示例程式碼:

import strutils except `%`, toUpper

# doesn't work then:
echo "$1" % "abc".toUpper

注意:如果匯入的模組中並沒有匯出排除的識別符號的話,nim編譯器是不會給出報警或異常的

 

include語句

include語句完全不同於import語句,

include語句會迫使編譯器把一個檔案的原始碼“包含”到另一個檔案中。

需要把一個檔案拆分成多個檔案的時候include語句很有用

include fileA, fileB, fileC

 

import語句中的模組名

import語句中的模組名可以設定別名

import strutils as su, sequtils as qu

echo su.format("$1", "lalelu")

如果你用了別名的話,那麼原來的模組名稱就不起作用了

如果一個模組在某個子目錄中

可以使用如下三種辦法來匯入該模組

import lib.pure.strutils, lib/pure/os, "lib/pure/times"

注意:雖然模組在子目錄中,但是模組名並不包含路徑

下面的程式碼是錯誤的:

import lib.pure.strutils
echo lib.pure.strutils

下面這種程式碼設定也沒有任何意義

import lib.pure.strutils as strutils

 

from...import...語句

如果你只想匯入某一個模組的指定符號,那麼你就可以使用這種語句

來看下面的程式碼:

from strutils import `%`

echo "$1" % "abc"
# 但開發人員還是可以用完全限定符呼叫這個模組的其他方法:
echo strutils.replace("abc", "a", "z")

如果你想迫使開發人員必須在主調模組中使用完全限定符來呼叫被調模組的符號

那麼你可以使用,下面這種方法

rom strutils import nil

 

Export語句

下來看下面三個模組的程式碼

# module B
type MyObject* = object
# module A
import B
export B.MyObject

proc `$`*(x: MyObject): string = "my object"
# module C
import A

# B.MyObject has been imported implicitly here:
var x: MyObject
echo($x)

模組A把模組B中的符號匯出出來了

這樣模組C就不用再匯入模組B了

相關文章