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 的集合核心函数(first
、conj
等)在设计上不需要反映标准集合。
但是,如果需要,您可以对从 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
反编译的代码
如何定义记录集合或记录向量?
我有这段代码:
(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 的集合核心函数(first
、conj
等)在设计上不需要反映标准集合。
但是,如果需要,您可以对从 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
反编译的代码