简体   繁体   English

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

[英]Clojure - How to Declare a Collection or Vector of a Record

How Can I define a Record Collection or a Vector of Records? 如何定义记录集合或记录向量?

I have this snippet code: 我有以下代码段代码:

(defrecord Transaction [a, b, c])

I want define a Transaction collection called LastTransactions to implement a function like this: 我想定义一个称为LastTransactions的Transaction集合来实现如下功能:

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

First Question, is that the right way to do that? 第一个问题,这是正确的方法吗?

Second, How can i declare that structure? 第二,如何声明该结构?

Clojure's type hints don't offer any type validation - you can use Clojure Spec or Plumatic Schema for that. Clojure的类型提示不提供任何类型验证-您可以为此使用Clojure SpecPlumatic Sc​​hema They only serve for the compiler to prevent reflection when Java methods are called on the parameters. 它们仅用于编译器,以防止在参数上调用Java方法时发生反射。 For that purpose, you don't need to type hint a vector since Clojure's core functions for collections ( first , conj , etc.) by design don't require reflection on standard collections. 为此,您不需要键入提示向量,因为Clojure的集合的核心功能( firstconj等)不需要设计标准集合。

However, if you need, you can type-hint the elements that you extract from the lastTransaction sequence, for example: 但是,如果需要,可以键入提示从lastTransaction序列中提取的元素,例如:

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

Type-hints are used to avoid reflection. 类型提示用于避免反射。 They are not used to statically type function or constructor args. 它们不用于静态键入函数或构造函数args。

Just use basic ^java.util.List type-hint instead of ^LastTransactions . 只需使用基本的^java.util.List类型提示而不是^LastTransactions In this case, any use of wrong lastTransactions in the body of the function will fail with ClassCastException . 在这种情况下,在函数主体中使用错误的lastTransactions都会导致ClassCastException失败。 However, it won't check the type of elements in that list. 但是,它不会检查该列表中元素的类型。 To do so, use type hinting everytime you work with elements of lastTransactions . 为此,每次使用lastTransactions元素时lastTransactions使用类型提示。

Example 1 with type hinting : 具有类型提示的示例1

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

In this case, decompiled java code will look like: 在这种情况下,反编译的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);
    }
}

Example 2 without type hinting : 示例2没有类型提示

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

decompiled to: 反编译为:

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

Compare the resulted return statements: 比较结果返回语句:

with type hinting 带类型提示

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

without type hinting 没有类型提示

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

PS: code decompiled by using clj-java-decompiler PS:使用clj-java-decompiler反编译的代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM