【发布时间】:2020-11-22 06:59:09
【问题描述】:
以下作品:
((resolve (symbol "first")) [1 2 3])
;; => 1
为什么这样想是不对的,
((read-string "first") [1 2 3])
;; => nil
应该有效,但它没有? (我得到nil。)
【问题讨论】:
标签: clojure
以下作品:
((resolve (symbol "first")) [1 2 3])
;; => 1
为什么这样想是不对的,
((read-string "first") [1 2 3])
;; => nil
应该有效,但它没有? (我得到nil。)
【问题讨论】:
标签: clojure
(resolve (symbol "first")) 的返回值可能是应用于参数的 Var clojure.core/first。
(read-string "first") 的返回值是符号 first,它也适用于参数。但是将符号用作函数具有不同的含义。参数应该是一个map,返回值相当于(get a-map the-symbol)。
任何实现clojure.lang.IFn 的类型都可以在函数位置。使用符号作为带有向量参数的函数返回 nil 而不是失败的原因在于 implementation details of IFn for the Symbol 类型(在这种特殊情况下为 arity 1):
public Object invoke(Object obj) {
return RT.get(obj, this);
}
RT.get() 检查obj 是否实现了ILookup,如果是则调用ILookup.valAt()。 Clojure 向量确实实现了ILookup,但它们实现了expect an integer as the provided key and return nil for anything else。
public Object valAt(Object key, Object notFound){
if(Util.isInteger(key))
{
int i = ((Number) key).intValue();
if(i >= 0 && i < count())
return nth(i);
}
return notFound;
}
public Object valAt(Object key){
return valAt(key, null);
}
【讨论】:
胡安是对的:
(resolve (symbol "first")) => <#clojure.lang.Var #'clojure.core/first>
(read-string "first") => <#clojure.lang.Symbol first>
我们可以验证:
(ns tst.demo.core
(:use tupelo.core tupelo.test))
(dotest
(let [first-var (var clojure.core/first)
first-sym (symbol "first")]
(is= 1 (first-var [1 2 3])) ; automatically converted from a var => funciton by Clojure
(is= nil (first-sym [1 2 3]))))
另请参阅this answer,了解有关 Clojure Var 对象的双重间接的更多信息。
【讨论】: