0

介绍

我正在研究一个用 Scala 编写的 API。我使用数据传输对象 (DTO) 作为传递给 API 函数的参数。DTO 将由 API 的用户实例化。

由于 API 非常抽象/通用,我想指定 API 应该操作的对象的属性。例子:

case class Person(name: String, birthdate: Date)

Person“P”的实例被传递给 API 时,API 需要知道它应该操作的“P”的属性:只是namebirthdate,或两者兼而有之。

所以我需要设计一个 DTO,它包含“P”本身的实例、某种属性声明以及关于“P”类型的附加信息。

基于字符串的方法

一种方法是使用Strings 来指定“P”的属性以及它的类型。这将相对简单,因为Strings 非常轻巧且众所周知。由于包、类型和成员的正式符号为Strings,因此声明将在一定程度上结构化。另一方面,String必须验证 -declarations,因为用户可能会传递无效String的 s。我可以想象用专用类型而不是 来表示属性的类型String,这可能具有增加结构的好处,甚至这些类型的设计也可能只存在有效的实例。

反射 API 方法

当然,我想到了反射 API,我正在尝试用反射 API 的类型声明属性。不幸的是,scala 2.10.x 反射 API 有点不直观。有名称、符号、镜像、类型、类型标签可能会引起一些混乱。

基本上,我看到了使用 s 进行属性声明的两种替代方法String

  1. 带有反射 API 的“名称”的属性声明
  2. 使用反射 API 的“符号”(尤其是 TermSymbol)的属性声明

如果我这样做,据我所知,构建 DTO 的 API 用户将不得不处理反射 API 及其名称/符号。API 的实现也必须使用反射 API。所以有两个地方有反射代码,用户必须至少对反射 API 有一点了解。

问题

但是我不知道这些方法有多重要:

  • 名称或符号的构建成本高吗?
  • 反射 API 是否对昂贵的操作结果进行任何缓存,还是我应该注意这一点?
  • 名称和符号是否可以通过网络传输到另一个 JVM?
  • 它们是可序列化的吗?

主要问题:scala 反射 API 名称或符号是否足以在传输对象内部使用?

使用反射 API 执行此操作似乎很复杂。欢迎任何提示。以及有关其他替代方案的任何提示。

PS:我还没有包含我自己的代码,因为我的 API 很复杂,反射部分处于相当的实验状态。Maye 我可以稍后提供一些有用的东西。

4

1 回答 1

1

1a) 名称易于构造且重量轻,因为它们比字符串多一点。

1b) 符号不能由用户构造,而是在使用类似staticClassor之类的 API 解析名称时在内部创建member。对此类 API 的首次调用通常涉及从ScalaSignature注释中解包符号所有者的类型签名,因此它们的成本可能很高。随后的调用使用已经加载的签名,但仍然支付在哈希表(1)中按名称查找的成本。declaration成本低于member,因为declaration不考虑基类。

2) 类型签名(例如类成员列表、参数+方法的返回类型等)被延迟加载,因此被缓存。Java 和 Scala 反射工件之间的映射也被缓存(2)。据我所知,其余的(例如子类型检查)通常是未缓存的,只有一些小例外。

3-4)反射工件取决于它们的宇宙,目前无法序列化(3)

于 2013-10-07T20:38:43.680 回答