Macro trả về danh sách sau đó được đánh giá trong không gian tên mà nó được gọi, không phải không gian tên được xác định. Điều này khác với các hàm đánh giá trong không gian tên mà chúng được xác định. Đây là vì các macro trả về mã để chạy, thay vì chỉ chạy nó.
nếu tôi đi đến không gian tên khác, ví dụ hello.core
và mở rộng một cuộc gọi đến tiếp theo ngày tôi nhận được:
hello.core> (macroexpand-1 '(next-date weeks 2))
(weeks 2)
sau đó sau khi mở rộng, tuần được giải quyết từ hello.core, trong đó nó là tất nhiên là không được định nghĩa. để khắc phục điều này, chúng ta cần biểu tượng trả về để mang thông tin không gian tên với nó.
may mắn thay bạn có thể giải quyết rõ ràng biểu tượng trong không gian tên với ns-resolve
. Phải mất một namespace và một biểu tượng và cố gắng để tìm thấy nó trong không gian tên trở về con số không nếu nó không tìm thấy
(ns-resolve 'clj-time.core (symbol "weeks"))
#'clj-time.core/weeks
tiếp theo macro của bạn sẽ được tham gia một biểu tượng và một số vì vậy chúng tôi có thể phân chia với các cuộc gọi rõ ràng để symbol
(ns-resolve 'clj-time.core 'weeks)
#'clj-time.core/weeks
vì vậy bây giờ bạn chỉ cần một chức năng giải quyết các chức năng và sau đó tạo ra một danh sách các chức năng giải quyết tiếp theo là số,
(defmacro next-date [interval freq]
(list (ns-resolve 'clj-time.core interval) freq))
Trong macro trên tất cả nó làm là thực hiện cuộc gọi chức năng mà được gọi là lập tức, vì vậy bạn thậm chí không cần một macro cho việc này:
(defn next-date [interval freq]
((ns-resolve 'clj-time.core interval) freq))
(next-date 'weeks 2)
#<Weeks P2W>
phiên bản phi vĩ mô đòi hỏi bạn phải trích dẫn khoảng vì nó cần nó không được đánh giá trước khi bạn có thể tra cứu nó. Những gì macro thực sự mua bạn ở đây không phải bao gồm báo giá, với chi phí yêu cầu tất cả người gọi yêu cầu clj-time
tất nhiên bạn cũng có thể yêu cầu thời gian ở mọi nơi, nhưng đó không thực sự là điểm .
Tại sao bạn cần viết macro. Điều này có thể được thực hiện bởi một chức năng bình thường không? Hãy nhớ rằng: bạn không bao giờ nên viết macro khi một hàm sẽ thực hiện. – viebel