Clojure - 如何声明记录的集合或向量

Clojure - How to Declare a Collection or Vector of a Record

如何定义记录集合或记录向量?

我有这段代码:

(defrecord Transaction [a, b, c])

我想定义一个名为 LastTransactions 的事务集合来实现如下函数:

(defn can-authorize
    "Validate Authorization by Transaction"
    [^Transaction transaction, ^LastTransactions lastTransactions]
    (... business logic)
    )

第一个问题,这是正确的方法吗?

其次,如何声明该结构?

Clojure 的类型提示不提供任何类型验证 - 您可以使用 Clojure Spec or Plumatic Schema。它们仅供编译器在对参数调用 Java 方法时防止反射。为此,您不需要键入向量提示,因为 Clojure 的集合核心函数(firstconj 等)在设计上不需要反映标准集合。

但是,如果需要,您可以对从 lastTransaction 序列中提取的元素进行类型提示,例如:

(defn can-authorize
  "Validate Authorization by Transaction"
  [^Transaction transaction, lastTransactions]
  ...
  (for [^Transaction t lastTransactions]
    (...do-something-with t))

类型提示用于避免反射。它们不用于静态类型函数或构造函数参数。

只需使用基本 ^java.util.List 类型提示而不是 ^LastTransactions。在这种情况下,任何在函数体中使用错误的 lastTransactions 都会失败并返回 ClassCastException。但是,它不会检查该列表中元素的类型。为此,请在每次使用 lastTransactions.

的元素时使用类型提示

带有类型提示的示例 1:

(defn can-authorize
  [^Transaction transaction, ^java.util.List lastTransactions]
  (.size lastTransactions) 
)

在这种情况下,反编译的 java 代码将如下所示:

// Decompiling class: user$can_authorize
import clojure.lang.*;
import java.util.*;

public final class user$can_authorize extends AFunction
{
    public static Object invokeStatic(final Object transaction, Object lastTransactions) {
        final Object o = lastTransactions;
        lastTransactions = null;
        return ((List)o).size();
    }

    public Object invoke(final Object transaction, final Object lastTransactions) {
        return invokeStatic(transaction, lastTransactions);
    }
}

没有类型提示的示例 2:

(defn can-authorize [^String transaction,  lastTransactions]
             (.size lastTransactions))

反编译为:

// Decompiling class: user$can_authorize
import clojure.lang.*;

public final class user$can_authorize extends AFunction
{
    public static Object invokeStatic(final Object transaction, Object lastTransactions) {
        final Object target = lastTransactions;
        lastTransactions = null;
        return Reflector.invokeNoArgInstanceMember(target, "size", false);
    }

    public Object invoke(final Object transaction, final Object lastTransactions) {
        return invokeStatic(transaction, lastTransactions);
    }
}

比较结果 return 语句:

带有类型提示

return ((List)o).size();

没有类型提示

return Reflector.invokeNoArgInstanceMember(target, "size", false);

PS:使用clj-java-decompiler

反编译的代码