5

Làm việc trên các ví dụ sau đây trong "Clojure trong hành động":Lỗi sử dụng "áp dụng" chức năng trong Clojure: "Không biết làm thế nào để tạo ISeq từ: java.lang.Long" (. P 63)

(defn basic-item-total [price quantity] 
    (* price quantity)) 

(defn with-line-item-conditions [f price quantity] 
    {:pre [(> price 0) (> quantity 0)] 
    :post [(> % 1)]} 
    (apply f price quantity)) 

Đánh giá về REPL:

(with-line-item-conditions basic-item-total 20 1) 

Kết quả trong ngoại lệ sau đây bị ném:

Don't know how to create ISeq from: java.lang.Long 
    [Thrown class java.lang.IllegalArgumentException] 

Nó xuất hiện ngoại trừ đang được thứ sau khi quy trình áp dụng được đánh giá.

+1

'apply' là hàm, không phải macro. – amalloy

Trả lời

8

Đối số cuối cùng cho apply được coi là sequence of arguments. Trong trường hợp của bạn, việc sử dụng có thể trông như thế này:

(defn with-line-item-conditions [f price quantity] 
    {:pre [(> price 0) (> quantity 0)] 
    :post [(> % 1)]} 
    (apply f [price quantity])) 

apply rất hữu ích khi bạn đang làm việc với một danh sách các đối số. Trong trường hợp của bạn, bạn có thể chỉ cần gọi hàm:

(defn with-line-item-conditions [f price quantity] 
    {:pre [(> price 0) (> quantity 0)] 
    :post [(> % 1)]} 
    (f price quantity)) 
+1

Cảm ơn - Tôi thấy bây giờ trong trường hợp macro được áp dụng, trình tự phải là một vectơ. Điều này không rõ ràng sau khi đọc mô tả sau khi đánh giá (doc áp dụng): "Áp dụng fn f cho danh sách đối số được hình thành bằng cách thêm các đối số can thiệp vào args." – dtg

+2

Vâng, một số chuỗi tài liệu có thể khá mờ. [The cheatsheet] (http://clojure.org/cheatsheet) là một nơi tuyệt vời để sử dụng ví dụ. – Beyamor