【问题标题】:in clojure symbols are functions, why? [duplicate]在clojure中,符号是函数,为什么? [复制]
【发布时间】:2021-07-04 15:32:24
【问题描述】:

在 clojue 中,我可以将符号作为函数调用:

('sym 1 2) => 2
('sym 1) => nil
('sym 1 2 3) => ArityException

有什么意义? clojure 中如何使用符号作为函数?

【问题讨论】:

    标签: clojure symbols


    【解决方案1】:

    符号作为函数的行为方式与关键字的行为方式相同。他们工作 比如get,用于查找。

    (println ('+ {'+ + '- -}))
    ; → #object[clojure.core$_PLUS_ 0xe3cee7b clojure.core$_PLUS_@e3cee7b]
    

    2-arity 版本,如 get,提供用于提供后备,以防万一 该符号不是您查找它的关键。由于 Clojure 非常宽松 输入后,您将返回nil(或您的第一个默认的2 默认示例)为1,不支持按键查找。

    【讨论】:

    • 谢谢,不知道。什么是用例?使用关键字很明显,关键字是数据的标签,因此您说通过该标签获取数据。 Symbol 是一个命名指针,它指向一个有值的 var(位置)。那是一个数据选择器吗?
    • @Sharas 关键字和符号都是内部字符串的一种形式,实际上,关键字实现是基于符号实现的。在 Clojure 中,通常任何 Clojure 值都可以用作映射中的键,但像 Symbol 和 Keyword 这样的内部字符串对此目的特别有效。然而,关键字在地图中作为键而不是符号更常见。符号通常用于其他事情。由于它们适合作为映射中的键,因此它们都具有 Clojure 函数的接口是很实用的。
    • @Sharas 变量是变量。符号更接近关键字。您通常处理符号的地方是在宏中,或者如果您编写“编译”的东西。您会看到这些功能在您的日常代码库中很少使用,例如 :syms 解构。
    【解决方案2】:

    符号用于在符号本身作为键出现的映射中查找值。在地图上可以这样使用:

    ('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 类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-11
      • 1970-01-01
      • 1970-01-01
      • 2012-08-30
      • 2021-12-07
      • 2011-04-09
      • 1970-01-01
      相关资源
      最近更新 更多