[英]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 Spec或Plumatic Schema 。 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的集合的核心功能(
first
, conj
等)不需要设计标准集合。
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.