【发布时间】:2021-07-04 15:32:24
【问题描述】:
在 clojue 中,我可以将符号作为函数调用:
('sym 1 2) => 2
('sym 1) => nil
('sym 1 2 3) => ArityException
有什么意义? clojure 中如何使用符号作为函数?
【问题讨论】:
在 clojue 中,我可以将符号作为函数调用:
('sym 1 2) => 2
('sym 1) => nil
('sym 1 2 3) => ArityException
有什么意义? clojure 中如何使用符号作为函数?
【问题讨论】:
符号作为函数的行为方式与关键字的行为方式相同。他们工作
比如get,用于查找。
(println ('+ {'+ + '- -}))
; → #object[clojure.core$_PLUS_ 0xe3cee7b clojure.core$_PLUS_@e3cee7b]
2-arity 版本,如 get,提供用于提供后备,以防万一
该符号不是您查找它的关键。由于 Clojure 非常宽松
输入后,您将返回nil(或您的第一个默认的2
默认示例)为1,不支持按键查找。
【讨论】:
:syms 解构。
符号用于在符号本身作为键出现的映射中查找值。在地图上可以这样使用:
('a {'a 2 'b 3})
;; => 2
('a {'b 3})
;; => nil
('a {'b 3} 119)
;; => 119
不要害怕查看Symbol 类的source code。它有两个实现IFn 接口的方法。 IFn 接口由 Clojure 函数实现。这是Symbol类中该接口的两个invoke方法的实现:
public Object invoke(Object obj) {
return RT.get(obj, this);
}
public Object invoke(Object obj, Object notFound) {
return RT.get(obj, this, notFound);
}
注意上面代码中this关键字的出现,这是符号本身作为key参数传递给clojure.lang.RT.get方法以便从地图中查找值.
实际上,Symbol 类通过AFn 抽象类间接实现IFn 接口,如Symbol.java 文件的at the top 所示:public class Symbol extends AFn。
有什么意义? 答案:方便、简洁。您也可以调用get 函数在地图中查找符号:
(get {'a 2 'b 3} 'a)
;; => 2
请记住,在 Clojure 中,您通常可以使用任何 Java 对象作为 Clojure 哈希映射中的键,只要它实现了 .hashcode 和 .equals 方法。符号是interned strings 的一种形式,因此查找起来非常有效。因为它们适合用作地图中的键,所以为了方便,很自然地实现IFninterface。
另一个与Symbol 相关的类是Keyword,它也是一种内部字符串。 Keyword 类实际上在内部基于 Symbol 类。
【讨论】: