14

所以有列表?,序列?,向量?,地图?等等以确定参数是什么类型的集合。

有什么好方法来区分

  • 地图(即包含键值对的东西)
  • 一个集合(即包含值的东西)
  • 一个非集合值,如字符串。

有没有比这更好的方法

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

4 回答 4

9

usingseq?尽可能简洁和干净。

clojure.contrib.core 定义:

可排序的?
    功能
    用法:(seqable?x)
    如果 (seq x) 成功则返回 true,否则返回 false。

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

它完成了您提出的一项重要or声明

  • 已经有序列了
  • clojure.lang.Seqable 的一个实例
  • 可迭代的实例
  • 数组
  • 一个字符串
  • java.util.Map 的实例
于 2010-10-25T22:07:03.007 回答
5

我们不要忘记sequential?

user=> (sequential? [])
true
user=> (sequential? '())
true
user=> (sequential? {:a 1})
false
user=> (sequential? "asdf")
false
于 2016-08-06T11:43:26.110 回答
4

现在的函数seq只做这个:

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

RT.java最新版本的 Clojure 中,您会发现:

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());
    }
}

一个ASeq或一个LazySeq已经是一个序列。ASeqable是知道如何返回自身序列的东西。

这留下了诸如 Java 核心类之类的东西,它们应该是可序列化的,但 Clojure 不能改变它来添加seq方法。这些当前已硬编码到此列表中。如果有一天实现发生变化,我不会感到惊讶,也许使用协议来扩展 Java 核心类?

于 2010-10-26T18:34:30.280 回答
0

所有 seqable 都实现 clojure.lang.Seqable 标记:

(instance? clojure.lang.Seqable x)

Clojure 1.9 提供seqable?

于 2017-06-25T09:05:28.057 回答