Có thể chia không gian tên Clojure trên nhiều tệp nguồn khi thực hiện biên dịch trước thời hạn với :gen-class
không? Làm thế nào để (:main true)
và (defn- ...)
đi vào chơi?
Câu trả lời:
Chắc chắn bạn có thể, trên thực tế, clojure.core
chính không gian tên được chia theo cách này và cung cấp một mô hình tốt mà bạn có thể theo dõi bằng cách xem trong src/clj/clojure
:
core.clj
core_deftype.clj
core_print.clj
core_proxy.clj
..etc..
Tất cả các tệp này tham gia để xây dựng clojure.core
không gian tên duy nhất .
Một trong số này là tệp chính, được đặt tên khớp với tên không gian tên để nó sẽ được tìm thấy khi ai đó đề cập đến nó trong dấu :use
hoặc :require
. Trong trường hợp này, tệp chính là clojure/core.clj
, và nó bắt đầu bằng một ns
biểu mẫu. Đây là nơi bạn nên đặt tất cả cấu hình không gian tên của mình, bất kể tệp nào khác của bạn có thể cần chúng. Điều này thường cũng bao gồm :gen-class
, vì vậy một cái gì đó như:
(ns my.lib.of.excellence
(:use [clojure.java.io :as io :only [reader]])
(:gen-class :main true))
Sau đó, tại những vị trí thích hợp trong tệp chính của bạn (phổ biến nhất là ở cuối) sử dụng load
để đưa vào tệp trợ giúp của bạn. Trong clojure.core
nó trông như thế này:
(load "core_proxy")
(load "core_print")
(load "genclass")
(load "core_deftype")
(load "core/protocols")
(load "gvec")
Lưu ý rằng bạn không cần thư mục hiện tại làm tiền tố, cũng như không cần .clj
hậu tố.
Mỗi tệp trợ giúp phải bắt đầu bằng cách khai báo không gian tên nào mà chúng đang trợ giúp, nhưng nên làm như vậy bằng cách sử dụng in-ns
hàm. Vì vậy, đối với không gian tên ví dụ ở trên, tất cả các tệp trợ giúp sẽ bắt đầu bằng:
(in-ns 'my.lib.of.excellence)
Đó là tất cả những gì nó cần.
Bởi vì tất cả các tệp này đang xây dựng một không gian tên duy nhất, mỗi hàm bạn xác định có thể nằm trong bất kỳ tệp chính hoặc tệp trợ giúp nào. Tất nhiên, điều này có nghĩa là bạn có thể xác định các gen-class
chức năng của mình trong bất kỳ tệp nào bạn muốn:
(defn -main [& args]
...)
Lưu ý rằng các quy tắc xác định thứ tự thông thường của Clojure vẫn áp dụng cho tất cả các hàm, vì vậy bạn cần đảm bảo rằng bất kỳ tệp nào xác định một hàm đều được tải trước khi bạn cố gắng sử dụng hàm đó.
Bạn cũng đã hỏi về (defn- foo ...)
biểu mẫu xác định một không gian tên-chức năng riêng tư. Các hàm được xác định như vậy cũng như các :private
vars khác có thể nhìn thấy từ bên trong không gian tên nơi chúng được xác định, vì vậy các tệp chính và tất cả các tệp trợ giúp sẽ có quyền truy cập vào các vars riêng tư được xác định trong bất kỳ tệp nào được tải cho đến nay.