为什么在Clojure中带有conj的列表需要撇号?

时间:2015-11-27 01:44:03

标签: clojure

在结束时,如果您运行以下代码:

let postImage = PFObject(className: "Vaccine")
postImage["expiration"] = expiration.text

let imageData = UIImageJPEGRepresentation(imageToPost.image!, 0.2)
let imageFile = PFFile(name: "dogumentImage.jpg", data: imageData!)
postImage["dogumentImage"] = imageFile

let ifActiveQuery = PFQuery(className: "Vaccine")
ifActiveQuery.whereKey("userID", equalTo: self.userID)
ifActiveQuery.whereKey("vaccineType", equalTo: self.vaccineDocument)
ifActiveQuery.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
    if let vaccine = objects {
        for object in vaccine {
            print(object.objectId)
            if object.objectId == nil {
                postImage.saveInBackgroundWithBlock {
                    (succeeded: Bool, error: NSError?) -> Void in
                    self.activityIndicator.stopAnimating()
                    UIApplication.sharedApplication().endIgnoringInteractionEvents()
                    self.dismissViewControllerAnimated(true, completion:nil)
                    self.expirationField.text = ""
                    self.imageToPost.image = UIImage(named: "addDocument.jpg")
                }
            } else {
                let deleteAlert = UIAlertController(title: "Update Dogument Information?", message: "All old data will be lost.", preferredStyle: UIAlertControllerStyle.Alert)
                deleteAlert.addAction(UIAlertAction(title: "Yes", style: .Default, handler: { (action: UIAlertAction!) in
                    object.deleteInBackground()
                    postImage.saveInBackgroundWithBlock {
                        (succeeded: Bool, error: NSError?) -> Void in
                        self.activityIndicator.stopAnimating()
                        UIApplication.sharedApplication().endIgnoringInteractionEvents()
                        self.dismissViewControllerAnimated(true, completion: nil)
                        self.expirationField.text = ""
                        self.imageToPost.image = UIImage(named: "addDocument.jpg")
                    }
                }))
                deleteAlert.addAction(UIAlertAction(title: "Cancel", style: .Default, handler: { (action: UIAlertAction!) in
                        print("Canceled Delete")
                }))
            }
        }
    }
})

错误并说:

(conj (1 2 3) 4)

但是,如果在列表前放置撇号,它就会运行正常

ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn

我的问题是,这个撇号究竟做了什么,为什么这个列表实际上是必要的?

我注意到使用矢量

时不会发生这种情况
(conj '(1 2 3) 4)

事实上,即使您使用撇号(conj [1 2 3] 4) ,它仍然可以正常工作并返回相同的结果。

撇号究竟做了什么,为什么列表需要它,但是矢量不是? (抱歉,如果这是一个初学者/愚蠢的问题,我还在学习。非常感谢一个彻底的答案)

1 个答案:

答案 0 :(得分:2)

list(括号)和vector(括号)之间存在根本区别,列表用于函数调用,向量只是向量文字。

撇号是quote的读者宏,它会抑制评估。例如,(+ 1 2)从源文件读入时评估为3,但'(+ 1 2)作为listclojure.lang.PersistentList读入,符合代码是lisp中的数据。另一方面,引用向量只是vector本身。

因此,在您的情况下,(conj (1 2 3) 4)在读入时会尝试使用参数12调用名为3的函数,难怪它会失败。但是引用的列表或向量可以附加一个额外的元素。