list?、seq?、vector?、map? があります。など、引数がどのタイプのコレクションであるかを判別します。
の違いを伝える良い方法は何ですか
- マップ (つまり、キーと値のペアを含むもの)
- コレクション (つまり、値を含むもの)
- 文字列のような非コレクション値。
よりも良い方法はありますか
#(or (seq? %) (list? %) etc)
list?、seq?、vector?、map? があります。など、引数がどのタイプのコレクションであるかを判別します。
の違いを伝える良い方法は何ですか
よりも良い方法はありますか
#(or (seq? %) (list? %) etc)
using seq?
は、可能な限り簡潔でクリーンです。
clojure.contrib.core は以下を定義します:
シーケンシャル? 関数 使用法: (seqable? x) (seq x) が成功する場合は true、そうでない場合は false を返します。
http://clojure.github.com/clojure-contrib/core-api.html
それはあなたが提案したことを1つの大きなor
声明で行います
忘れないようにしましょうsequential?
:
user=> (sequential? [])
true
user=> (sequential? '())
true
user=> (sequential? {:a 1})
false
user=> (sequential? "asdf")
false
関数seq
は今これだけを行います:
(. clojure.lang.RT (seq coll))
Clojure の最新バージョンにはRT.java
、次のものがあります。
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());
}
}
anASeq
または aLazySeq
はすでに seq です。ASeqable
は、それ自体の seq を返す方法を知っているものです。
これにより、Java コア クラスのようなものが残ります。これらは、seqable である必要がありますが、Clojure が変更してseq
メソッドを追加することはできません。それらは現在、このリストにハードコードされています。実装がいつか変更されても驚かないでしょうか。代わりにプロトコルを使用して Java コア クラスを拡張するのでしょうか?
すべての seqable は clojure.lang.Seqable マーカーを実装しています:
(instance? clojure.lang.Seqable x)
Clojure 1.9 が提供するseqable?