2010-10-25 27 views
13

Vì vậy, có danh sách ?, seq ?, vector ?, map? và như vậy để xác định loại đối số thu thập là gì.Clojure: tìm hiểu xem bộ sưu tập có khả năng thu thập được không

gì là một cách tốt để nói sự khác biệt giữa

  • một bản đồ (tức là một cái gì đó có chứa cặp khóa-giá trị)
  • một bộ sưu tập (tức là một cái gì đó có chứa các giá trị)
  • một giá trị không thu như một chuỗi.

Có cách nào tốt hơn so với

#(or (seq? %) (list? %) etc) 

Trả lời

9

sử dụng seq? khoảng càng ngắn gọn và sạch sẽ như nó được.

clojure.contrib.core định nghĩa:

 
seqable? 
    function 
    Usage: (seqable? x) 
    Returns true if (seq x) will succeed, false otherwise. 

http://clojure.github.com/clojure-contrib/core-api.html

nó những gì bạn đề nghị với một or tuyên bố lớn của

  • đã là một seq
  • một thể hiện của clojure.lang.Seqable
  • nil
  • thể hiện của Iterable
  • một mảng
  • một chuỗi
  • thể hiện của java.util.Map
+0

@kotarak cảm ơn bạn đã sửa liên kết :) –

+0

Tôi tin rằng điều này đã chuyển ... mọi cập nhật về vị trí của nó? – jayunit100

+0

Trong phiên bản hiện tại của Clojure (1.5) có thể truy cập được? hiện đang sống trong clojure.core.incubator (repo @ https://github.com/clojure/core.incubator) –

4

Chức năng seq ngay bây giờ chỉ thực hiện điều này:

(. clojure.lang.RT (seq coll)) 

Trong RT.java trong phiên bản mới nhất của Clojure, bạn sẽ tìm thấy:

static public ISeq seq(Object coll){ 
    if(coll instanceof ASeq) 
     return (ASeq) coll; 
    else if(coll instanceof LazySeq) 
     return ((LazySeq) coll).seq(); 
    else 
     return seqFrom(coll); 
} 

static ISeq seqFrom(Object coll){ 
    if(coll instanceof Seqable) 
     return ((Seqable) coll).seq(); 
    else if(coll == null) 
     return null; 
    else if(coll instanceof Iterable) 
     return IteratorSeq.create(((Iterable) coll).iterator()); 
    else if(coll.getClass().isArray()) 
     return ArraySeq.createFromObject(coll); 
    else if(coll instanceof CharSequence) 
     return StringSeq.create((CharSequence) coll); 
    else if(coll instanceof Map) 
     return seq(((Map) coll).entrySet()); 
    else { 
     Class c = coll.getClass(); 
     Class sc = c.getSuperclass(); 
     throw new IllegalArgumentException("Don't know how to create ISeq from: " + c.getName()); 
    } 
} 

An ASeq hoặc LazySeq đã là một seq. Một Seqable là một cái gì đó mà biết làm thế nào để trả lại một seq của chính nó.

Điều đó để lại những thứ như các lớp lõi Java, cần phải có thể bắt giữ nhưng Clojure không thể thay đổi để thêm phương thức seq. Những mã này hiện được mã hóa cứng vào danh sách này. Tôi sẽ không ngạc nhiên nếu việc thực hiện thay đổi một ngày nào đó, có thể sử dụng các giao thức để mở rộng các lớp lõi Java thay thế?

4

Đừng quên sequential?:

user=> (sequential? []) 
true 
user=> (sequential? '()) 
true 
user=> (sequential? {:a 1}) 
false 
user=> (sequential? "asdf") 
false 
0

Tất cả seqables thực hiện marker clojure.lang.Seqable:

(instance? clojure.lang.Seqable x) 

Clojure 1.9 cung cấp seqable?

Các vấn đề liên quan